zoukankan      html  css  js  c++  java
  • 多重背包优化算法

    二进制优化

    https://vjudge.net/problem/POJ-1742

    题面:有n中面额的钱,每种有ci个,问1--m里有多少个数能用这些钱组成。

     1 int n,m,a[105],num[105],dp[100005];
     2 void comdp(int w,int v)
     3 {
     4     int i;
     5     for(i=w; i<=m; i++)
     6         dp[i]=max(dp[i],dp[i-w]+v);
     7 }
     8 void zeroone(int w,int v)
     9 {
    10     int i;
    11     for(i=m; i>=w; i--)
    12         dp[i]=max(dp[i],dp[i-w]+v);
    13 }
    14 void multidp(int w,int v,int cnt)//此时开始多重背包,dp[i]表示背包中重量为i时所包含的最大价值
    15 {
    16     if(cnt*w>=m)//此时相当于物品数量无限进行完全背包
    17     {
    18         comdp(w,v);
    19         return;
    20     }
    21     int k=1;//否则进行01背包转化,具体由代码下数学定理可得
    22     while(k<=cnt)
    23     {
    24         zeroone(k*w,k*v);
    25         cnt-=k;
    26         k*=2;
    27     }
    28     zeroone(cnt*w,cnt*v);
    29     return ;
    30 }
    31 int main()
    32 {
    33     while(~scanf("%d%d", &n, &m)){
    34         if(!n&&!m) break;
    35         for(int i = 0; i <= m; i++){
    36             dp[i] = -INF;
    37         }
    38         dp[0]=0;
    39         for(int i = 0; i < n; i++){
    40             scanf("%d", &a[i]);
    41         }
    42         for(int i = 0; i < n; i++){
    43             scanf("%d", &num[i]);
    44         }
    45         for(int i = 0; i < n; i++)
    46             multidp(a[i], a[i], num[i]);
    47         int ans=0;
    48         for(int i = 1; i <= m; i++){
    49             if(dp[i]>0)
    50                 ans++;
    51         }
    52         printf("%d
    ", ans);
    53     }
    54     return 0;
    55 }

    这里dp要换成bool数组表示能否组成的状态,节省时间。

     1 bool dp[MAXN];
     2 int V;
     3 P p[MAXN];
     4 void zero(int cost)
     5 { 
     6     for(int i=V;i>=cost;i--) 
     7         dp[i] |= dp[i-cost];
     8 } 
     9 void complet(int cost) 
    10 { 
    11     for(int i=cost;i<=V;i++) 
    12         dp[i] |= dp[i-cost]; 
    13 } 
    14 void multi(int cost, int amount) 
    15 { 
    16     if(cost*amount>=V){ 
    17         complet(cost); 
    18         return; 
    19     } 
    20     int k=1; 
    21     while(k<amount){ 
    22         zero(k*cost);
    23         amount-=k; 
    24         k=k*2; 
    25     } 
    26     zero(amount*cost);
    27 } 
    28 //多重背包的二进制优化  V-背包总容量 cost-单件物品花费(重量)  amount-单件物品数量  weight-单件物品价值 
    29 int main()
    30 {
    31     int n, m;
    32     while(scanf("%d %d", &n, &m), n + m)
    33     {
    34         V = m;
    35         memset(dp, 0, sizeof(dp));
    36         for(int i = 0; i < n; i++)
    37                scanf("%d", &p[i].first);
    38         for(int i = 0; i < n; i++)
    39             scanf("%d", &p[i].second);
    40         //sort(p, p + n);
    41         dp[0] = 1;
    42         for(int i = 0; i < n; i++){
    43             multi(p[i].first, p[i].second);
    44         }
    45         int ans = 0;
    46         for(int i = 1; i <= m; i++){
    47             ans += dp[i];
    48         }
    49         printf("%d
    ", ans);
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    uwsgi
    protobuf c++ API
    memcached 第二篇----安装使用
    ice grid配置使用第二篇------实际使用
    ICE BOX 配置,使用----第一篇
    可视化资料收集
    Protocol Buffers
    ice grid 完整部署过程
    django组件之ajax
    关于Django在写小项目的一些小注意事项
  • 原文地址:https://www.cnblogs.com/Surprisezang/p/9128018.html
Copyright © 2011-2022 走看看