zoukankan      html  css  js  c++  java
  • 混合背包问题

    混合背包问题

     

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

     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
    ",dp[n][m]);
    31     return 0;
    32 }
  • 相关阅读:
    报表设计器的使用之一:入门
    统计图开发之二:点图元
    统计图开发之一:画法定义
    集算器之五:序表
    集算器之四:程序流程
    忏悔录
    请不要离我而去
    所想和所做 所梦和所成
    做出改变,不断改变。
    Linux 操作命令
  • 原文地址:https://www.cnblogs.com/wsy107316/p/14086645.html
Copyright © 2011-2022 走看看