Description
Input
Output
Sample Input
3 2 4 3 10 1 2 10 0 5 100 0 5 80 0 3 2 4 3 10 1 2 10 0 5 100 0 5 80 1 0 0 0
Sample Output
Case 1: 120 Case 2: 100
机智的我虽然看出是这个分类依旧卡了3个多点的题,状态好次==
题意:给女朋友买一堆礼物,每个礼物有一个快乐值,有n个备选的,其中有一部分是必买的,总共有两张支票,价值v1,v2,花钱少了不给退,两张支票不能凑在一起用,而且有一个礼物是免费的,问女友最多可以多快乐?
做法:最开始的思路是:dp[v1][v2],三重循环,一维是礼物,二维、三维分别是dp的两维,然后循环的时候犯了一个低级错误,j,k正常来说是大于cost[i]循环到cost[i[就停止了,但是这个题不能停啊!比方说j循环到cost[i[停了,但是k不一定不满足啊,这个题是两维啊!
然后,题中要求有一个是免费的,我受之前做过的题(貌似是饭卡吧)的影响,纠结于是要找出一个最贵的还是最快乐的?觉得是应该找出来一个“快乐值”最大的,然而并不是的。这个题的处理方法是再加一维dp表示是否用过这个免费的机会(貌似之前树形dp做过吧)之后,dp转移是很容易可以想到的==
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int cost1[309],hap1[309],cost0[309],hap0[309],dp[505][55][2],n,v1,v2; int main() { // freopen("cin.txt","r",stdin); //freopen("out.txt","w",stdout); int cas=1; while(~scanf("%d%d%d",&v1,&v2,&n)) { if(v1==0&&v2==0&&n==0)break; memset(dp,0,sizeof(dp)); int l0=0,l1=0,maxh=0,maxn; for(int i=0;i<n;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(c==1) { cost1[l1]=a; hap1[l1++]=b; maxh+=b; } if(c==0) { cost0[l0]=a; hap0[l0++]=b; } } for(int i=0;i<l1;i++) { for(int j=v1;j>=0;j--) { for(int k=v2;k>=0;k--) { dp[j][k][1]=max(dp[j][k][1],dp[j][k][0]+hap1[i]); if(j>=cost1[i]) dp[j][k][0]=max(dp[j][k][0],dp[j-cost1[i]][k][0]+hap1[i]), dp[j][k][1]=max(dp[j][k][1],dp[j-cost1[i]][k][1]+hap1[i]); if(k>=cost1[i]) dp[j][k][0]=max(dp[j][k][0],dp[j][k-cost1[i]][0]+hap1[i]), dp[j][k][1]=max(dp[j][k][1],dp[j][k-cost1[i]][1]+hap1[i]); // printf("i=%d,j=%d,k=%d,dp0=%d,dp1=%d\n",i,j,k,dp[j][k][0],dp[j][k][1]); } } } if(dp[v1][v2][1]<maxh)maxn=-1; else { for(int i=0;i<l0;i++) { for(int j=v1;j>=0;j--) { for(int k=v2;k>=0;k--) { if(dp[j][k][0]>=maxh) dp[j][k][1]=max(dp[j][k][1],dp[j][k][0]+hap0[i]); if(j>=cost0[i]&&dp[j-cost0[i]][k][0]>=maxh) dp[j][k][0]=max(dp[j][k][0],dp[j-cost0[i]][k][0]+hap0[i]); if(j>=cost0[i]&&dp[j-cost0[i]][k][1]>=maxh) dp[j][k][1]=max(dp[j][k][1],dp[j-cost0[i]][k][1]+hap0[i]); if(k>=cost0[i]&&dp[j][k-cost0[i]][0]>=maxh) dp[j][k][0]=max(dp[j][k][0],dp[j][k-cost0[i]][0]+hap0[i]); if(k>=cost0[i]&&dp[j][k-cost0[i]][1]>=maxh) dp[j][k][1]=max(dp[j][k][1],dp[j][k-cost0[i]][1]+hap0[i]); // printf("i=%d,j=%d,k=%d,dp0=%d,dp1=%d\n",i,j,k,dp[j][k][0],dp[j][k][1]); } } } maxn=dp[v1][v2][1]; } printf("Case %d: %d\n\n",cas++,maxn); } return 0; }