洛谷1064 金明的预算方案 01背包变种

题目链接:https://www.luogu.com.cn/problem/P1064

就是一个01背包的变种问题,只是选择的可能情况不同。对于01背包,对第i个物品,选择的情况有两种:选择或者不选择,而本问题中选择的情况有五种:对于一个主件来说,可以不选择,可以只选择主件,可以选择主件+第一个附件(如果有的话),还可以选择主件+第二个附件(如果有的话),还可以选择主件+第一个附件+第二个附件(如果有的话)。唯一的注意点就是编号是连续的,附件的编号不起作用,所属主件的编号是输入中有序的编号,循环过程需要判断是否是主件,因为主件必须要有。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define dbg(args) cout<<#args<<":"<<args<<endl;
17 #define inf 0x3f3f3f3f
18 #define maxn 100005
19 int n,m,t;
20 int v[maxn],w[maxn],cnt[maxn],ww[maxn][5],vv[maxn][5],dp[maxn];
21 //cnt表示第k个主件的附件数量 ,ww:附件的权重 vv:附件的价值 
22 int main()
23 {
24     //freopen("P1064_5.txt","r",stdin);
25     //freopen("output.txt","w",stdout);
26     std::ios::sync_with_stdio(false);
27     scan(m);
28     scan(n);
29     int q,x,y;
30     f(i,1,n)
31     {
32         scan(x);
33         scan(y);
34         scan(q);
35         if(q)
36         {
37             cnt[q]++;//表示第i编号的是附件,q的第cnt个附件,附件最多是两个 
38             ww[q][cnt[q]]=x*y;
39             vv[q][cnt[q]]=x;
40         }
41         else 
42         {
43             w[i]=x*y;
44             v[i]=x;
45         }
46         
47     }
48         f(i,1,n)
49             for(int j=m;j>=v[i]&&v[i]!=0;j--)//v[i]不等于零表示该编号的主件存在 
50             {
51                 dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
52                 if(!cnt[i])continue;//没有附件 
53                 if(cnt[i]>=1)
54                 {
55                     if(j-v[i]-vv[i][1]>=0)
56                     dp[j]=max(dp[j],dp[j-v[i]-vv[i][1]]+w[i]+ww[i][1]);
57                 }
58                 if(cnt[i]>=2)
59                 {
60                     if(j-v[i]-vv[i][2]>=0)
61                     {
62                         dp[j]=max(dp[j],dp[j-v[i]-vv[i][2]]+w[i]+ww[i][2]);
63                     }
64                     if(j-v[i]-vv[i][1]-vv[i][2]>=0)
65                         {
66                             dp[j]=max(dp[j],dp[j-v[i]-vv[i][1]-vv[i][2]]+w[i]+ww[i][1]+ww[i][2]);
67                         }
68                     
69                 }
70             }
71             pf("%d",dp[m]);
72  } 

猜你喜欢

转载自www.cnblogs.com/randy-lo/p/12455023.html