题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4501
题目大意:
一共有n件商品,每件商品有一个购买价钱,购买积分,得分价值。
现有k件物品的选购机会,有v1元钱,v2积分,问能获得的最大得分价值是多少。
解题思路:
dp[i][j][k]表示有i元钱,j积分和k个免费商品的机会,能获得的最大的得分价值。
对每件商品一共有四种选择,1、用钱买 2、用积分换 3、用一个免费商品的名额 4、什么都不用
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<stack> #include<queue> #define eps 1e-6 #define INF (1<<20) #define PI acos(-1.0) using namespace std; int dp[110][110][10]; //dp[i][j][k]表示有i人民币,j积分,k次免费的机会能够获得的最大价值 struct Thing { int a,b,val; }thing[110]; int main() { int n,v1,v2,k; while(scanf("%d%d%d%d",&n,&v1,&v2,&k)!=EOF) { int sum=0; for(int i=1;i<=n;i++) { scanf("%d%d%d",&thing[i].a,&thing[i].b,&thing[i].val); sum+=thing[i].val; } memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) for(int q=k;q>=0;q--) for(int j=v1;j>=0;j--) for(int p=v2;p>=0;p--) { if(j>=thing[i].a&&p>=thing[i].b) //如果能够用积分或钱 { dp[j][p][q]=max(max(dp[j-thing[i].a][p][q]+thing[i].val,dp[j][p-thing[i].b][q]+thing[i].val),dp[j][p][q]); if(q>=1) //如果能用免费的名额 dp[j][p][q]=max(dp[j][p][q],dp[j][p][q-1]+thing[i].val); } else if(j<thing[i].a&&p<thing[i].b) //如果钱和积分都不能用 { if(q>=1) dp[j][p][q]=max(dp[j][p][q],dp[j][p][q-1]+thing[i].val); } else if(j<thing[i].a) //只能用积分 { dp[j][p][q]=max(dp[j][p-thing[i].b][q]+thing[i].val,dp[j][p][q]); if(q>=1) dp[j][p][q]=max(dp[j][p][q],dp[j][p][q-1]+thing[i].val); } else //只能用钱 { dp[j][p][q]=max(dp[j-thing[i].a][p][q]+thing[i].val,dp[j][p][q]); if(q>=1) dp[j][p][q]=max(dp[j][p][q],dp[j][p][q-1]+thing[i].val); } } printf("%d\n",dp[v1][v2][k]); } return 0; }