EDPC E - Knapsack 2
ナップサック2
考え方
ABCでいうと、D問題級。
重さ制限がある中で、価値の合計を最大化する問題。
典型的な $0/1$ ナップサック問題である。
ただし、今回は重さ制限 $W$ が非常に大きい。
そのため、D 問題のように重さを DP テーブルの添字にすると間に合わない。
そこで、価値の方を DP テーブルの添字にする。
dp[j] を、総価値 $j$ での最小総重量とする。
各品物について、使う場合と使わない場合を比較しながら DP テーブルを更新する。
ただし、同じ品物を $2$ 回以上使わないようにするため、dp は価値が大きい方から更新する。
最後に、最小総重量が $W$ 以下である価値のうち、最も大きいものを探せばよい。
詳しくは「ナップサック問題」の記事参照。
計算量は $O(N\sum V)$。
入力例1での動作
入力を受け取る。
n: 3
m: 8
w: {3, 4, 5}
v: {30, 50, 60}
価値合計は $30+50+60=140$ なので、今回は dp[0] から dp[140] までを用意する。
dp[j] を、総価値 $j$ での最小総重量とする。
何も品物を見ていない状態では、総価値 $0$ だけが重さ $0$ で達成できる。
それ以外は INF で初期化する。
dp[0]: 0
その他: INF
$1$ 個目の品物 $(w,v)=(3,30)$ を見る。
この品物を使うと、総価値 $30$ を総重量 $3$ で達成できる。
dp[0] : 0
dp[30]: 3
その他: INF
$2$ 個目の品物 $(w,v)=(4,50)$ を見る。
この品物だけを使うと、総価値 $50$ を総重量 $4$ で達成できる。
また、$1$ 個目と $2$ 個目を両方使うと、総価値 $80$ を総重量 $7$ で達成できる。
dp[0] : 0
dp[30]: 3
dp[50]: 4
dp[80]: 7
その他: INF
$3$ 個目の品物 $(w,v)=(5,60)$ を見る。
この品物を使うことで、いくつかの総価値を更新できる。
- 総価値 $60$ は、$3$ 個目だけを使って総重量 $5$
- 総価値 $90$ は、$1$ 個目と $3$ 個目を使って総重量 $8$
- 総価値 $110$ は、$2$ 個目と $3$ 個目を使って総重量 $9$
- 総価値 $140$ は、$1$ 個目から $3$ 個目を全て使って総重量 $12$
dp[0] : 0
dp[30] : 3
dp[50] : 4
dp[60] : 5
dp[80] : 7
dp[90] : 8
dp[110]: 9
dp[140]: 12
その他: INF
重さ制限は $8$ なので、最小総重量が $8$ 以下であるものだけが使える。
その中で最も大きい総価値は $90$ なので、答えは $90$。
注意点
総重量は、int 型からはみ出る。
long long 型を用いること。
別解
特になし。