E - Knapsack 2
キーワード
解説
に対して、 を次のように定義する。(ただし、 )
番目までの品物から価値の総和が 以上となるように選んだときの重さの最小値
と初期化する。 番目の品物まで使って良いとき、 番目のしなものを使う場合と使わない場合の二通り考えられる。
- 使わない場合は、 番目までの品物で、価値 を達成できるため、 番目まで使った時の最小重みと等しい。
- 使う場合は、 番目までの品物で、価値 を達成できる最小重みに を加えたもの。
よって次のような漸化式が立てられる。
最終的な答えは、 を満たす最大の となる。 は について単調増加であるため、二分探索で求めることもできる。
提出コード
int main() {
int n, w; cin >> n >> w;
vector<int> W(n), V(n); rep(i,0,n) cin >> W[i] >> V[i];
vector<vector<ll>> dp(n+1, vector<ll>(MAX, 1e18));
dp[0][0] = 0;
rep(i,1,n+1) {
rep(j,0,MAX) {
dp[i][j] = dp[i-1][j];
if(j-V[i-1] >= 0) dp[i][j] = min(dp[i][j], dp[i-1][j-V[i-1]] + W[i-1]);
}
}
rrep(j,MAX-1,0) if(dp[n][j] <= w) {
cout << j << endl;
break;
}
}