私はN個の数値のシーケンスを与えました(4≦N≦150)。 1つのインデックスi(0 < i < N)がピックされ、左と右の数、つまりi-1とi + 1で乗算されます。次にi番目の番号が削除されます。これは、シーケンスに2つの数字だけが残るまで実行されます。目指すのは、これらの製品の最小の合計を見つけることです。これは明らかに、インデックスが選択される順序に依存します。ダイナミックプログラミングを使用して中間要素が削除されたトリプレット積の最小合計
など。シーケンス44,45,5,39,15,22,10の場合、最小の合計は、次の順序でインデックスを使用する17775 となります。1-> 3-> 4-> 5-> 2これは合計: 44 * 45 * 5 + 5 * 39 * 15 + 5 * 15 * 22 + 5 * 22 * 10 + 44 * 5 * 10 = 9900 + 2925 + 1650 + 1100 + 2200 = 17775
解決策
public static int smallestSum(List<Integer> values) {
if (values.size() == 3)
return values.get(0) * values.get(1) * values.get(2);
else {
int ret = Integer.MAX_VALUE;
for (int i = 1; i < values.size() - 1; i++) {
List<Integer> copy = new ArrayList<Integer>(values);
copy.remove(i);
int val = smallestSum(copy) + values.get(i - 1) * values.get(i) * values.get(i + 1);
if (val < ret) ret = val;
}
return ret;
}
}
しかし、この解決法は、小さなNでは実現可能ですが、より大きい数値では実現できません。私が探しているのは、反復動的プログラミングの手法を使ってこれを行う方法です。
は、これは」doesnの要素の削除は適切に考慮されていないため、機能しません。例えば、提供された例示的なシーケンスは、37770を出力する。なぜなら、再帰呼び出しは、最初の呼び出しで呼び出されるので、再帰呼び出しの値[i-1]の最初の反復でi = 1で始まるときは呼び出し元の値[ i = 1であるため、ループは最初の+ 1 = 2で開始し、再帰呼び出しの値[i-1]はvalues [i]と等しくなります。実際にi番目の要素は再帰呼び出しには現れないので、配列から削除する必要があります。そうでなければ無視しなければなりません。削除された要素を追跡することによって – user538331
@ user538331 'first'と' last'の代わりに 'i-1'と' i + 1'を使ったバグを修正しました。改訂版は正しいと思われます。 –
ありがとうございます。私は自分自身で残りを得ることができるはずだと思う – user538331