一道DP题,不知道为什么,2006年的题DP好像有点多。每个物件只有一个,有容量的上限,其实就是一道01背包。
dp【i】表示i元钱时候的所求的最大值,可以推出dp【i】=max{dp【i】,dp【i-v[j]】+w【j】};但这道题还有一个条件,附件只能在主件之后购买,所以我们就考虑购买这个物品之后去购买它的附件,因为最多只有2个附件,所以题还是比较简单的。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int dp[32005],f[61][2],v[61],tot[61],tot_f[61][2];//tot表示价格和重要值的乘积,f表示一个物体和它的附件 int n,m; int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int p,q; cin>>v[i]>>p>>q; if(!q){//如果没有主件 tot[i]=p*v[i]; } else{//如果有主件,所属主件的附件数+1 f[q][0]++; f[q][f[q][0]]=v[i]; tot_f[q][f[q][0]]=v[i]*p; } } for(int i=1;i<=m;i++){ for(int j=n;j>=v[i];j--){ if(j>=v[i])//购买一个主件 dp[j]=max(dp[j],dp[j-v[i]]+tot[i]); if(j>=v[i]+f[i][1])//一个主件和他的一个附件 dp[j]=max(dp[j],dp[j-v[i]-f[i][1]]+tot[i]+tot_f[i][1]); if(j>=v[i]+f[i][1]+f[i][2])//一个主件和他的两个附件 dp[j]=max(dp[j],dp[j-v[i]-f[i][1]-f[i][2]]+tot[i]+tot_f[i][1]+tot_f[i][2]); } } cout<<dp[n]; }