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

          多重背包介于0-1背包和完全背包之间:有容积为V的背包给定一些物品,每种物品包含体积w,价值v和数量k,求用该背包能

    装下的最大价值总量。可以将多重背包问题直接转化到0-1背包上去,即将每种物品被均视为k种不同的物品。

         0-1背包的介绍可见另一博文 http://www.cnblogs.com/yuxiaoba/p/8458135.html

         完全背包介绍可见另一博文 http://www.cnblogs.com/yuxiaoba/p/8458447.html

         可以采取一种技巧性地拆分,将原数量为k的物品拆分为若干组,每组物品看成一件物品,其价值和重量为该组中所有物品的

    价值重量总和,每组物品包含的原物品个数分别为:1、2、4、……k-2^c+1, 其中c为使 k-2^c+1大于0的最大整数。这种类似于二进制的拆分,不仅可以将物品数量大大降低,同时通过对这些若干原物品组合得到的新物品的不同组合,可以得到0到k之间任意件物品的价值重量和。

    珍惜现在,感恩生活

    题目描述

    急!灾区的食物依然短缺! 
    为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。 
    请问:你用有限的资金最多能采购多少公斤粮食呢? 

    输入描述:

    输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。

    输出描述:

    对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。
    示例1

    输入

    1
    8 2
    2 100 4
    4 100 2

    输出

    400
     1 #include <stdio.h>
     2 #include <limits.h>
     3 
     4 int max( int a,int b)
     5 {
     6     return a > b ? a:b;
     7 }
     8 
     9 struct E
    10 {
    11     int w;  //大米价格
    12     int v;  //大米重量
    13 } list[2001];
    14 int dp[101];
    15 
    16 int main()
    17 {
    18     int T,n,m;
    19     int p,h,k;
    20     int i,j;
    21     int index,c;
    22     scanf("%d",&T);
    23 
    24     while( T-- )
    25     {
    26         scanf("%d%d",&n,&m);
    27         index = 0;  //拆分后物品总数
    28         for( i=1; i<=m; i++)
    29         {
    30             c = 1;
    31             scanf("%d%d%d",&p,&h,&k);
    32             while( k-c>0)
    33             {
    34                 k -= c;
    35                 list[++index].w = c*p;
    36                 list[index].v = c*h;
    37                 c *= 2;
    38             }
    39             list[++index].w = p*k;  //补充不足指数的差值
    40             list[index].v = h*k;
    41         }
    42         for( i=0; i<=n; i++) dp[i]=0;
    43         for( i=1; i<=index; i++)   //对拆分后的物品进行0-1背包
    44         {
    45             for( j=n; j>=list[i].w; j--)
    46                 dp[j] = max( dp[j],dp[j-list[i].w]+list[i].v);
    47         }
    48         printf("%d
    ",dp[n]);
    49     }
    50     return 0;
    51 }
    在这个国度中,必须不停地奔跑,才能使你保持在原地。如果想要寻求突破,就要以两倍现在速度奔跑!
  • 相关阅读:
    iOS学习之自定义UItableViewCell
    iOS学习之UItableView
    iOS学习之懒加载
    iOS学习之根据文本内容动态计算文本框高度的步骤
    iOS学习之导航条NavigationControl的一些属性设置
    iOS: TableView如何刷新指定的cell 或section
    时间戳比较
    UIScrollView 去掉下面的滚动条
    iOS中navigationItem修改标题的颜色
    swift 下storyboard的页面跳转和传值
  • 原文地址:https://www.cnblogs.com/yuxiaoba/p/8460105.html
Copyright © 2011-2022 走看看