洛谷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 }

 

posted @ 2019-01-24 13:04  宇興  阅读(215)  评论(0编辑  收藏  举报