混合背包问题

混合背包问题

 

 

 

 二进制优化代码,具体见代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1000010;
 5 const int mod = 1e9+7;
 6 const int inf = 0x3f3f3f3f;
 7 int n,m,v[maxn],w[maxn],dp[maxn];
 8 int cnt;
 9 
10 int main()
11 {
12     scanf("%d%d",&n,&m);
13     for(int i=1;i<=n;i++){
14         int a,b,ss; scanf("%d%d%d",&a,&b,&ss);
15         if( ss<0 ) ss=1;//把01背包转换成只有一个的多重背包
16         else if( ss==0 ) ss=m/a;//如果是完全背包,在最优情况下,只能取总体积/该物品体积向下取整
17 
18         for(int j=1;j<=ss;j<<=1){
19             cnt ++;
20             v[cnt] = j*a;
21             w[cnt] = j*b;
22             ss -= j;
23         }
24         if( ss>0 ){
25             cnt ++;
26             v[cnt] = ss*a;
27             w[cnt] = ss*b;
28         }
29     }
30 
31     for(int i=1;i<=cnt;i++){
32         for(int j=m;j>=v[i];j--){
33             dp[j] = max(dp[j], dp[j-v[i]]+w[i]);
34         }
35     }
36     cout<<dp[m]<<endl;
37     return 0;
38 }

 队列优化代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1000010;
 5 const int mod = 1e9+7;
 6 const int inf = 0x3f3f3f3f;
 7 int n,m,q[maxn],dp[1010][1010];
 8 int cnt;
 9 
10 int main()
11 {
12     scanf("%d%d",&n,&m);
13     for(int i=1;i<=n;i++){
14         int a,b,ss; scanf("%d%d%d",&a,&b,&ss);
15         if( ss<0 ) ss=1;//把01背包转换成只有一个的多重背包
16         else if( ss==0 ) ss=m/a;//如果是完全背包,在最优情况下,只能取总体积/该物品体积向下取整
17 
18         for(int j=0;j<a;j++){
19             int head=0, tail=1;
20             q[0] = 0;
21             for(int k=j;k<=m;k+=a){
22                 while( head<tail && q[head]<k-ss*a ) head++;
23                 dp[i][k] = dp[i-1][k];
24                 if(head<tail) dp[i][k] = max(dp[i][k], dp[i-1][q[head]]+(k-q[head])/a*b);
25                 while( head<tail && dp[i-1][q[tail-1]]+(k-q[tail-1])/a*b<dp[i-1][k] ) tail--;
26                 q[tail++] = k;
27             }
28         }
29     }
30     printf("%d\n",dp[n][m]);
31     return 0;
32 }

 

posted @ 2020-12-04 16:48  swsyya  阅读(150)  评论(0编辑  收藏  举报

回到顶部