洛谷P1064 金明的预算方案
1 //依赖关系最多2种 可以用分组背包水过 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define w first 5 #define v second 6 const int maxv=32005; 7 const int maxn=65; 8 int n,m,k,tot,f[maxv],ID[maxn]; 9 vector< pair<int,int> >d[maxn]; 10 int main() 11 { 12 scanf("%d%d",&m,&n); 13 for(int i=1,x,y,z;i<=n;++i) 14 { 15 scanf("%d%d%d",&x,&y,&z);//坑 注意审题 给出编号按输入顺序 16 if(!z) d[++tot].push_back(make_pair(x,y)),ID[i]=tot; 17 else d[ID[z]].push_back(make_pair(x,y)),ID[i]=ID[z]; 18 } 19 for(int i=1;i<=tot;++i) 20 { 21 d[i][0]=make_pair(d[i][0].w,d[i][0].w*d[i][0].v); 22 //直接把价值预处理成重要度乘体积 注意处理顺序 23 if(d[i].size()==2) d[i][1]=make_pair(d[i][1].w+d[i][0].w,d[i][1].v*d[i][1].w+d[i][0].v); 24 //一个附件 看成两组——只有主件/主件+附件 25 if(d[i].size()==3)//两个附件 看成四组——只有主件/主件+附件1/主件+附件2/主件+附件1+附件2 26 { 27 d[i].push_back(make_pair(d[i][0].w+d[i][1].w+d[i][2].w,d[i][0].v+d[i][1].v*d[i][1].w+d[i][2].v*d[i][2].w)); 28 d[i][1]=make_pair(d[i][1].w+d[i][0].w,d[i][1].v*d[i][1].w+d[i][0].v); 29 d[i][2]=make_pair(d[i][2].w+d[i][0].w,d[i][2].v*d[i][2].w+d[i][0].v); 30 } 31 } 32 for(int k=1;k<=tot;++k)//分组背包 33 for(int j=m;j>=0;--j) 34 for(int i=0;i<d[k].size();++i) 35 if(j>=d[k][i].w) f[j]=max(f[j],f[j-d[k][i].w]+d[k][i].v); 36 printf("%d",f[m]); 37 return 0; 38 }