题目链接
5 10000 3 1 4 6 2 5 7 3 4 99 1 55 77 2 44 66
255
//这道题目说句实话,我还没与想明白,当然是一维的方法还没有想明白。 //二维的就在这里给大家说一下: /* if(dp[i][kk-G[i][j].pr]!=-1) dp[i][kk]=max(dp[i][kk],dp[i][kk-G[i][j].pr]+G[i][j].v); if(dp[i-1][kk-G[i][j].pr]!=-1){ dp[i][kk]=max(dp[i][kk],dp[i-1][kk-G[i][j].pr]+G[i][j].v); ********* 这个代码块很重要******* 1.if(dp[i][kk-G[i][j].pr]!=-1) dp[i][kk]=max(dp[i][kk],dp[i][kk-G[i][j].pr]+G[i][j].v); 这个代码表示当我选择了眼前的这个物品的时候,判断我这个品牌是否已经选过一次了,如果选过,我可以接着选择; **************************************************************************************8 【for(int kk=m; kk>=G[i][j].pr; kk--)】这个代码大家应该以前经常见到过便是那01背包的模板代码中的一部分。 至于为什么放在这里,为了说明上面以及下面那个代码块的又来。为什么要如此的判断。 众所皆知,大家都明白,按照这种循环方式,可以防止前一次的操作在这一次产生不应该产生的影响, 知道的明白,当他首次进入另一个品牌的选择时,每一个dp里面都是-1,如果,在这之前存在着的不是-1,那么证明,已经选择了一个当前品牌的产品。 然后再已经选了的基础上,我在选一个。 如此下面那个代码块也是这么理解。 便是不管这个产品选没有选,我都在上一个品牌选了的基础上选这个品牌中的一个产品,代表着,此时我只选了当前这个品牌的一个。 ************************************************************************************** 2. if(dp[i-1][kk-G[i][j].pr]!=-1){ dp[i][kk]=max(dp[i][kk],dp[i-1][kk-G[i][j].pr]+G[i][j].v); 这个代码表示当我选择眼前的这个物品的时候,判断我的前面哪一个品牌是否选择了如果选择了,则可以选择了,如果没有选择证明,我的前一个品牌没有选到, 导致结果会是-1表示不满足条件 */ #include <cstdio> #include <vector> #include <cstring> #include <algorithm> using namespace std; int n,m,k; struct po { int v,pr; } pos; int id; vector<po>G[15]; void init(int mm) { for(int i=1; i<=mm; i++) { G[i].clear(); } } int dp[15][10000+5]; int main() { while(~scanf("%d%d%d",&n,&m,&k)) { init(k); memset(dp,-1,sizeof(dp)); for(int i=0; i<n; i++) { scanf("%d%d%d",&id,&pos.pr,&pos.v); G[id].push_back(pos); } for(int i=0; i<=10000; i++) { dp[0][i]=0; } for(int i=1; i<=k; i++) { for(int j=0; j<G[i].size(); j++) { for(int kk=m; kk>=G[i][j].pr; kk--) { if(dp[i][kk-G[i][j].pr]!=-1) dp[i][kk]=max(dp[i][kk],dp[i][kk-G[i][j].pr]+G[i][j].v); if(dp[i-1][kk-G[i][j].pr]!=-1) { dp[i][kk]=max(dp[i][kk],dp[i-1][kk-G[i][j].pr]+G[i][j].v); } } } } if(dp[k][m]<0) { printf("Impossible\n"); } else { printf("%d\n",dp[k][m]); } } return 0; }