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;
}