ABC015 D 高橋くんの苦悩 典型DP
ABC015 D 高橋くんの苦悩
問題概要
リンク参照
考察
- dp[j][k]をj枚すでに貼っていて,現在の幅がkの時の価値の最大としてdp
- 遷移は幅と枚数に余裕がある場合に以下の遷移を行う
dp[j+1][k+a[i]]=max(dp[j+1][k+a[i]],dp[j][k]+b[i]) (k+a[i] <= w && j+1 <= n)
ソースコード
#include<iostream> #include<vector> #include<algorithm> #include<cctype> #include<utility> #include<string> #include<cmath> #include<cstring> #include<queue> #include<map> #include<set> #include<climits> using namespace std; typedef long long int ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; #define ARRAY_MAX 100005 const int INF = INT32_MAX / 3; const ll MOD = 1e9 + 7; /******************************************************************************************/ int dp[55][10005]; int main() { int w, n, k; cin >> w >> n >> k; vector<pii> v(n); for (int i = 0; i < n; i++) { cin >> v[i].first >> v[i].second; } sort(v.begin(), v.end()); for (int i = 0; i < n; i++) { for (int k = n - 1; k >= 0; k--) { for (int j = w; j >= 0; j--) { if (j + v[i].first > w) { continue; } dp[k + 1][j + v[i].first] = max(dp[k + 1][j + v[i].first], dp[k][j] + v[i].second); } } } int ans = 0; for (int i = 0; i <= k; i++) { for (int j = 0; j <= w; j++) { ans = max(ans, dp[i][j]); } } cout << ans << endl; return 0; }