ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

ABC060 D - Simple Knapsack

問題
提出コード

解法

ナップサックと書いてあるのでとりあえずDPを考えます。
w_1をすべての重量から引いていくと、どれも0~3のいずれかの重量に置き換えることができます。
この重さを利用して、次のようなDPを考えていきます。
dp[i][j][k]=i番目までの荷物の中で、j個使用したときに、総重量がkとなるような組み合わせの中で最大の価値
すると、次のような遷移になります。
dp[i][j][k] = max(dp[i-1][j][k], dp[i - 1][j - 1][k - w[i]] + v[i])
左側がi番目の荷物を用いる場合、右側が用いない場合です。
そして、最終的な答えがどこに格納されているかを考えます。
仮にすべての荷物の重量が0であった場合、\frac{W}{w_1} が使用できる荷物の個数になります。 これをpとします。
重量が0のp個荷物を使うと決めた時、W-p×w_1の重さ分の荷物だけ入れることができます。
ということで、dp[n][p][x] (ただし、0 \leqq x \leqq W-p×w_1)
が答えの候補となるので、まずその中での最大値を記録しておきます。
次に、荷物をp-1個使用する時を考えます。すると、w_1だけ先ほどより多く重い荷物を入れることができるので、
dp[n][p-1][x] (ただし、0 \leqq x \leqq W-(p-1)×w_1)
が答えの候補となります。
これを繰り返していくと、
dp[n][p-j][x] (ただし、0 \leqq x \leqq W-(p-j)×w_1)
の中での最大値を求めれば、答えとなります。