mini notes

競技プログラミングの解法メモを残していきます。

DPまとめコンテスト  D - Knapsack 1

D - Knapsack 1

概要

N個の品物があり、品物iの重さがw_{i}、価値がv_{i}であるとする。
それぞれの品物高々1つナップサックに詰める。ナップサックに入れる品物の重さの総和をW以下とするとき、
ナップサックに詰める品物の価値の総和の最大値を求めよ。

制約

1 \leq N \leq 100
1 \leq W \leq 10^5
1 \leq w_i \leq W
1 \leq v_i \leq 10^9

方針

dp[i][j] : i番目の品物で重さj以下であるときの価値の最大値 とし、DPする。

解答

Submission #3940486 - Educational DP Contest / DP まとめコンテスト

#include <bits/stdc++.h>
 
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define rep(i,n) FOR(i,0,n)
#define RFOR(i,a,b) for(int i=(a)-1;i>=(b);i--)
#define rrep(i,n) RFOR(i,n,0)
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
 
int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
 
	int n, max_w;
	cin >> n >> max_w;
 
	int w[n], v[n];
	rep(i, n) cin >> w[i] >> v[i];
 
	ll dp[n+1][max_w+1] = {};
	// dp[i][j] : i番目の品物で重さj以下の価値の最大値
 
	for(int i = 1; i <= n; i++){
		for(int j = 0; j <= max_w; j++){
			dp[i][j] = max(dp[i][j], dp[i-1][j]);
			if(j - w[i-1] >= 0) dp[i][j] = max(dp[i][j], dp[i-1][j-w[i-1]] + v[i-1]);
		}
	}
 
	ll ans = 0;
	for(int i = 0; i <= max_w; i++) ans = max(ans, dp[n][i]);
	cout << dp[n][max_w] << endl;
}