zoukankan      html  css  js  c++  java
  • HDU 1085 多重背包转化为0-1背包问题

    题目大意:

    给定一堆1,2,5价值的硬币,给定三个数表示3种价值硬币的数量,任意取,找到一个最小的数无法取到

    总价值为M = v[i]*w[i](0<=i<3)

    那么在最坏情况下M个数都能取到 , M+1必然取不到

    所以给M+1个背包,往里面塞东西,最后由前往后检测,找到第一个无法取满的背包的体积

    这道题目里,每一种物品的v*w必然小于M+1,所以不出现完全背包的情况,全部采用多重背包转化为0-1背包解决问题即可

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 using namespace std;
     5 #define max(a,b) a>b?a:b
     6 const int N = 10000;
     7 
     8 int dp[N] , a[3] , M;
     9 int v[3] = {1 , 2 , 5};
    10 void zeroPack(int w , int v)
    11 {
    12     for(int i = M ; i >= w ; i--)
    13         dp[i] = max(dp[i-w]+v , dp[i]);
    14 }
    15 
    16 void multiPack(int n , int w , int v)
    17 {
    18     int t = 1;
    19     while(n > t){
    20         zeroPack(t*w , t*v);
    21         n -= t;
    22         t <<= 1;
    23     }
    24     if(n > 0) zeroPack(n*w , n*v);
    25 }
    26 
    27 int main()
    28 {
    29     while(1){
    30         M = 0;
    31         for(int i = 0 ; i<3 ; i++){
    32             scanf("%d" , a+i);
    33             M += a[i] * v[i];
    34         }
    35         if(M == 0) break;
    36         //这里加一表示可能你加起来的总值都能够取到,但是多加个一,那么必然会有一个最大值取不到
    37         M += 1; 
    38         memset(dp , 0 ,sizeof(dp));
    39         for(int i = 0 ; i<3 ; i++){
    40             multiPack(a[i] , v[i] , v[i]);
    41         }
    42 
    43         int k = 0;
    44         while(dp[k] == k) k++;
    45         printf("%d
    " , k);
    46     }
    47     return 0;
    48 }
  • 相关阅读:
    PV、UV、GMV
    保存Hive查询结果的方法 insert overwrite 用法
    Hive substr 函数截取字符串
    HIVE中join、semi join、outer join
    Hive 差集运算
    gitlab和github区别
    前端工程化 ESlint 配置
    ES6 WeakMap Map 区别
    js 创建数组方法以及区别
    eslint for...in 报错处理
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4181932.html
Copyright © 2011-2022 走看看