• 混合背包问题


    混合背包问题

     

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

     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 }
  • 相关阅读:
    MATLAB新手教程
    关于Core Location-ios定位
    《TCP/IP具体解释卷2:实现》笔记--IP的分片和重装
    利用JasperReport+iReport进行Web报表开发
    Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系
    Openfire开发配置,Openfire源码配置,OpenFire二次开发配置
    在Activity中为什么要用managedQuery()
    24点经典算法
    linux概念之时间与时区
    java实现第五届蓝桥杯大衍数列
  • 原文地址:https://www.cnblogs.com/wsy107316/p/14086645.html
Copyright © 2020-2023  润新知