zoukankan      html  css  js  c++  java
  • 多重背包问题

      学过01背包和完全背包后,多重背包就很好理解了。

      01背包物品个数只有一个,完全背包个数有无限个,多重背包个数为给定的数目。

      题目:

      输入的第一行为测试样例的个数T,接下来有T个测试样例。

      每个测试样例的第一行是物品种数N(1 ≤ N ≤ 100)和背包容量CC ≤ 10000)。

      接下来N行,每行三个正整数,Wi ,Vi 和 M( Wi ≤ 10000,    Vi ≤ 10000,    Mi ≤ 1000 ),分别表示第i种物品的重量 Wi ,价值 Vi ,及个数 Mi 。

      代码参考:https://blog.csdn.net/tinyguyyy/article/details/51203935

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=10006;
     5 const ll inf=0x3f3f3f3f;
     6 
     7 int n,W; ///n为物品种类,W为背包重量
     8 int w[maxn],v[maxn],M[maxn],dp[maxn]; ///w为重量,v为价值,M为个数
     9 
    10 void complete(int x) ///完全背包
    11 {
    12     for(int i=w[x];i<=W;i++)
    13         dp[i]=max( dp[i], dp[i-w[x]]+v[x]);
    14 }
    15 
    16 void zero_one(int cost,int weight) ///01背包
    17 {
    18     for(int i=W;i>=weight;i--)
    19         dp[i]=max(dp[i],dp[i-weight]+cost);
    20 }
    21 
    22 void solve()
    23 {
    24     for(int i=0;i<n;i++){
    25         if(w[i]*M[i]>W) complete(i); ///此处用完全背包,因为物品个数能放各个位置
    26         else{
    27             int mid=1;
    28             ///取得光的话,去遍历每种取法  
    29             ///这里用到是二进制思想,降低了复杂度  
    30             ///为什么呢,因为他取的1,2,4,8...与余数个该物品,打包成一个大型的该物品  
    31             ///这样足够凑出了从0-k个该物品取法  
    32             ///把复杂度从k变成了logk  
    33             ///如k=11,则有1,2,4,4,足够凑出0-11个该物品的取法  
    34             while( mid<M[i]){
    35                 zero_one(mid*v[i],mid*w[i]);
    36                 M[i]-=mid;
    37                 mid<<=1;
    38             }
    39             zero_one(M[i]*v[i],M[i]*w[i]);
    40         }
    41     }
    42 }
    43 
    44 int main()
    45 {
    46     ios::sync_with_stdio(0); std::cin.tie(0);
    47     int T;
    48     while(cin >> T){
    49         while(T--){
    50             cin >> n >> W;
    51             memset( dp, 0, sizeof dp);
    52 
    53             for(int i=0;i<n;i++)
    54                 cin >> w[i] >> v[i] >> M[i];
    55 
    56             solve();
    57 
    58             cout << dp[W] << endl;
    59         }
    60     }
    61 
    62     return 0;
    63 }
  • 相关阅读:
    禁用aspx页面的客户端缓存
    水晶报表的自动换行(转)
    ORACLE锁的管理
    同时使用有线和无线
    Oracle系统表的查询
    Oracle中临时表的深入研究
    我的My Life Rate
    [学习笔记]c#Primer中文版命名空间
    出差兰州·火车上
    [学习笔记]c#Primer中文版类设计、static成员、const和readonly数据成员
  • 原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/9034798.html
Copyright © 2011-2022 走看看