题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
//主要思想是动态规划 01背包的变种,在当拥有附件时主件放入背包将分情况讨论 #include <bits/stdc++.h> using namespace std; int main() { int N,m; cin>>N>>m; int pi[61][4]={0},we[61][4]={0},ac[61]={0},n0=0;//pi(i,j)表示第件主商品 第j种情况,j=0,1,2,3分别表示无附件,附件1,2,1+2; //ac【x】 表示x号商品附件数,默认为0 int dp[61][32000]={0}; for(int i=1;i<=m;i++) { int v,p,q; cin>>v>>p>>q; if(q==0) //主件 { pi[i][0]=v; we[i][0]=p*v; } else //附件 { ac[q]+=1; if(ac[q]==1) { pi[q][1]=v;//记录附件价格 we[q][1]=p*v; } else { pi[q][2]=v; we[q][2]=p*v; pi[q][3]=v+pi[q][1]; we[q][3]=p*v+we[q][1]; } } } for(int x=1;x<=m;x++) { for(int y=0;y<=N;y++) { if(pi[x][0]!=0 && pi[x][0]<=y) { switch (ac[x]) { case 0: dp[x][y]=max(dp[x-1][y],we[x][0]+dp[x-1][y-pi[x][0]]); break; case 1: if((pi[x][1]+pi[x][0])<=y) { dp[x][y]=max(dp[x-1][y], max(we[x][0]+dp[x-1][y-pi[x][0]],we[x][1]+we[x][0]+dp[x-1][y-pi[x][1]-pi[x][0]])); }else dp[x][y]=max(dp[x-1][y],we[x][0]+dp[x-1][y-pi[x][0]]); break; case 2: dp[x][y]=max(dp[x-1][y],we[x][0]+dp[x-1][y-pi[x][0]]); if(pi[x][1]+pi[x][0]<=y) dp[x][y]=max(dp[x][y],we[x][1]+we[x][0]+dp[x-1][y-pi[x][1]-pi[x][0]]); if(pi[x][2]+pi[x][0]<=y) dp[x][y]=max(dp[x][y],we[x][2]+we[x][0]+dp[x-1][y-pi[x][2]-pi[x][0]]); if(pi[x][3]+pi[x][0]<=y) dp[x][y]=max(dp[x][y],we[x][3]+we[x][0]+dp[x-1][y-pi[x][3]-pi[x][0]]); break; } } else { dp[x][y]=dp[x-1][y]; } } } //int x=1,y=300; //cout<<max(dp[x-1][y],we[x][0]+dp[x-1][y-pi[x][0]])<<endl; cout<<dp[m][N]<<endl; /* for(int i=1;i<=m;i++)//测试用 { if(ac[i]==0&&pi[i][0]!=0) { cout<<i<<' '<<"单主 "<<pi[i][0]<<" "<<we[i][0]<<endl; } else if(ac[i]==1) { cout<<i<<' '<<"单主 "<<pi[i][0]<<" "<<we[i][0]<<endl; cout<<i<<' '<<"+1 "<<pi[i][1]<<" "<<we[i][1]<<endl; } else if(ac[i]==2) { cout<<i<<' '<<"单主 "<<pi[i][0]<<" "<<we[i][0]<<endl; cout<<i<<' '<<"+1 "<<pi[i][1]<<" "<<we[i][1]<<endl; cout<<i<<' '<<"+2 "<<pi[i][2]<<" "<<we[i][2]<<endl; cout<<i<<' '<<"+1+2 "<<pi[i][3]<<" "<<we[i][3]<<endl; } }*/ } // 64 位输出请用 printf("%lld")