けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

鉄則本 A19 - Knapsack 1 (3Q, ★3)

ナップサック問題。鉄則本の問題なのでコードのみ。

問題概要

宝箱には  N 個の品物が入っている。品物  i の重さは  w_{i}、価値は  v_{i} である。

太郎君は、いくつかの品物を選んで持ち帰りたいと考えている。しかし、彼のナップザックには容量制限があるので、重さの合計が  W 以下になるようにする必要がある。

価値の合計としてあり得る最大の値はいくつか。

制約

  •  1 \le N \le 100
  •  1 \le W \le 10^{5}

コード

#include <bits/stdc++.h>
using namespace std;

int main() {
    int N, W;
    cin >> N >> W;
    vector<long long> w(N), v(N);
    for (int i = 0; i < N; i++) cin >> w[i] >> v[i];

    vector<vector<long long>> dp(N+1, vector<long long>(W+1, 0));
    for (int i = 0; i < N; i++) {
        for (int j = 0; j <= W; j++) {
            dp[i+1][j] = max(dp[i+1][j], dp[i][j]);
            if (j-w[i] >= 0) dp[i+1][j] = max(dp[i+1][j], dp[i][j-w[i]] + v[i]);
        }
    }
    cout << dp[N][W] << endl;
}