AT_arc042_c的题解

(一)

非常妙的 DP 题,可惜被翻译毁了。

题意:

你有一堆零食,每个零食有两个值 \(a_i\)\(b_i\)

要求选出集合 \(S\),使 \(\sum_{i \in S} a_i-\min_{i \in S} a_i\le p\),求最大的 \(\sum_{i \in S}b_i\)

一眼 DP。

先将 \(a_i\) 从小到大排序,每次循环更新 \(dp_0\) 的值为 \(\max{dp_0,a_i}\),然后就是 01背包。

(二)

AC 代码。

注意 \(dp_p\) 不一定是最大的。

#include<bits/stdc++.h>
using namespace std;
int n,p,dp[5010];
struct node{
	int x,y;
}a[5010];
bool cmp(node x,node y){
	return x.x<y.x;
}
signed main(){
	// freopen("in.txt","r",stdin);
	// freopen("out.txt","w",stdout);
	scanf("%d%d",&n,&p);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i].x,&a[i].y);
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++){
		for(int j=p;j>=a[i].x;j--){
			dp[j]=max(dp[j],dp[j-a[i].x]+a[i].y);
		}
		dp[0]=max(dp[0],a[i].y);
	}
	int ans=0;
	for(int i=1;i<=p;i++)ans=max(ans,dp[i]);
	printf("%d\n",ans);
    return 0;
}
posted @ 2024-05-15 20:54  Jerry_heng  阅读(17)  评论(0编辑  收藏  举报