金明的预算方案
#include<bits/stdc++.h> #define maxn 32005 using namespace std; int n,m,f[maxn],v,p,q,mw[maxn],mc[maxn],fw[maxn][3],fc[maxn][3]; int main() { register int i,j; scanf("%d%d",&n,&m); for(i=1;i<=m;++i) { scanf("%d%d%d",&v,&p,&q); if(!q) mw[i]=v,mc[i]=v*p;//mw表示主件i的价钱 mc表示主件i的~~~ else { ++fw[q][0];//表示主件q的附件数 fw[q][fw[q][0]]=v;//表示主件q的第几个附件的价钱 fc[q][fw[q][0]]=v*p;//不用说了噻 } } for(i=1;i<=m;++i) for(j=n;mw[i]!=0 && j>=mw[i];--j)//执行条件:i是主件 j大于主件i的价钱 { f[j]=max(f[j],f[j-mw[i]]+mc[i]);//主件i的取舍不装附件 if (j >= mw[i] + fw[i][1])//j大于主件和附件一的价钱(可以装) f[j] = max(f[j],f[ j - mw[i] - fw[i][1] ] + mc[i] + fc[i][1]); if (j >= mw[i] + fw[i][2])//j大于主件和附件二的价钱(可以装) f[j] = max(f[j],f[ j - mw[i] - fw[i][2] ] + mc[i] + fc[i][2]); if (j >= mw[i] + fw[i][1] + fw[i][2])// j大于主件和附件二和附件一的价钱(都可以装) f[j] = max(f[j],f[ j - mw[i] - fw[i][1] - fw[i][2] ] + mc[i] + fc[i][1] + fc[i][2]); } printf("%d",f[n]); return 0; } /*summary 背包问题就看有几种情况 e.g.01背包只有装与不装 这种有依赖的背包问题实则也只需理清有哪些情况*/