问题 B: WZK吃小鸡腿(chicken)

时间限制: 1 Sec  内存限制: 128 MB
提交: 53  解决: 23
[提交][状态][讨论版]

题目描述

As is known to all,WZK很能吃小鸡腿,但他的胃毕竟有一个最大容纳值c,否则胃中小鸡腿的巨大引力场和lōng场叠加后会有很可怕的效果。在CZYZ的食堂一共有n种小鸡腿有卖,每种小鸡腿都有有限的个数、重量和让WZK感到的满意度。WZK想在肚子不被撑爆的前提下,取得最大的满意度值。然后lōng场就得到了大大的power up。

输入

第一行:两个正整数n,c。 接着n行,每行三个正整数Ai,Mi,Wi,分别表示每种小鸡腿的个数、重量和满意度。

输出

一个正整数,表示最大的满意度。

样例输入

3 102 1 31 5 83 3 5

样例输出

19

提示

20%的数据ΣAi<=25

另外30%的数据c<=1000, ΣAi<=10000

对于100%的数据c<=10000,n<=100,Ai<=1000

这道题的算法是很明显的,多重背包。但是,普通的多重背包是三重循环的,所以肯定是要超时的(然而因为数据太水,被我三重循环水过了)。所以,这里要用到一个多重背包问题的常见优化,二进制优化。我们可以发现,多重背包的主要时间复杂度多在那一个多出来的k循环,也就是那个物品个数的循环。如果能把这个循环进行优化甚至去掉,那就可以节省大量的时间。而又因为多重背包的原型就是01背包,所以想到将其转换回01背包。那么就要将这些物品进行处理。原来的多重背包,那个k循环就相当于把有k个的一种物品分成了k个物品,但是这样过于浪费时间。所以在将物品进行重新处理的时候,我们 可以用到二进制的思想。首先,举个例子:1,2,4,8个物品可以组成1-15任何个数的物品。这一点就是二进制优化的核心内容。将物品的个数以二进制的方式进行处理,那么就可以在减少分的物品个数(这样子分肯定是要比k要小的)的同时能够达到1-原来个数之间的任意数。所以,我们在读入的时候可以对数据一一进行重新处理。如:一种物品有8个 每个物品重量为5  价值为10,那么进行处理之后就变成个数为1,2,4,1的四个物品,这四个物品的重量分别为5,10,20,5,价值分别为10,20,40,10。这样就让这一种物品变成了新的四个物品。将所有数据都进行处理完之后,只要再按01背包来一个双重循环即可解决。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
int tot,n,c;
int d[1000],a[11000],m[11000],w[11000],m1[11000],w1[11000],p[11000];
void put(int a0,int m0,int w0)//对数据进行重新处理
{int i=1;while (a0>d[i]){a0-=d[i];tot=tot+1;m1[tot]=d[i]*m0;w1[tot]=d[i]*w0;i=i+1;}tot=tot+1;m1[tot]=a0*m0;w1[tot]=a0*w0;
}
using namespace std;
int main()
{tot=0;scanf("%d%d",&n,&c);d[1]=1;for (int i=2;i<=15;i++)//产生二进制数d[i]=d[i-1]*2;for (int i=1;i<=n;i++){scanf("%d%d%d",&a[i],&m[i],&w[i]);put(a[i],m[i],w[i]);}for (int i=1;i<=tot;i++)//01背包的dp,注意这里i要到tot不是n,因为数据处理过了for (int j=c;j>=m1[i];j--)p[j]=max(p[j],p[j-m1[i]]+w1[i]);printf("%d",p[c]);}

多重背包二进制优化(wzk吃小鸡腿)相关推荐

  1. [多重背包+二进制优化]HDU1059 Dividing

    题目链接 题目大意: 两个人要把一堆宝珠,在不能切割的情况下按照价值平分,他们把宝珠分成6种价值,每种价值的宝珠n个. n<=200000 思考: 首先如果加和下来的价值是一个偶数 那么还分毛啊 ...

  2. HDU 5445 Food Problem 多重背包+二进制优化

    据说也可以用单调队列优化多重背包,但是我不会,所以还是选择了二进制优化... 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:先给n,m, ...

  3. POJ 1014 Dividing【多重背包+二进制优化】

    大意: 价值1, 2, 3, --, 6的物品分别a1, a2, --, a5, a6件 问能否把这些物品分成两份,使其具有相同的价值(所有物品必须全部用上) 分析: 给个物品有多件,即多重背包 只要 ...

  4. zcmu-1919: kirito(多重背包——二进制优化)

    Description 主角kirito是使用世界首款完全潜行游戏"刀剑神域(Sword Art Online)"的玩家.曾经很幸运的参与过封闭测试,并买下正式版的kirito,正 ...

  5. Dividing(多重背包二进制优化)

    题意:有价值为1-6的六种玻璃球,现在告诉你各种玻璃球的个数,问能否将这些玻璃球分成两份,使得两份的总价值相等 既然要等分,那么总价值必定是偶数,所以价值和为奇数是无法等分. 但价值和为偶数时,我们可 ...

  6. 12.14补卡,多重背包二进制优化

    题目链接:22背包专题 [Cloned] - Virtual Judge (vjudge.net) 思路:多重背包的主要思路就是把每一个物品分开放,从而达到每个物品拿与不拿全部遍历到.但是当物品数量过 ...

  7. hdu2844 Coins(普通的多重背包 + 二进制优化)

    看完背包九讲的多重背包之后,这题目应该可以轻松做出来了 模型: 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的 ...

  8. ZCMU-1919 kirito's 星爆气流斩(多重背包+二进制优化)

    Problem C: kirito's 星爆气流斩 Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 148  Solved: 37 [Submit][S ...

  9. ZCMU 1919: kirito's 星爆气流斩(多重背包+二进制优化)

    1919: kirito's 星爆气流斩 Time Limit: 2 Sec  Memory Limit: 128 MB Description 主角kirito是使用世界首款完全潜行游戏" ...

  10. hdu 2191 (多重背包二进制优化)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 实现代码: #include<bits/stdc++.h> using namespac ...

最新文章

  1. spring YML属性提示
  2. java中ofd文件转pdf_word文件转pdf怎么转?这一招轻松搞定Word转PDF
  3. Mysql优化(三):优化order by
  4. clientWidth、clientHeight、offsetWidth、offsetHeight以及scrollWidth、scrollHeight
  5. CSS 背景尺寸 background-size属性
  6. windows server 2008 - 隐藏磁盘分区 (2)
  7. Way to MongoDB
  8. Ajax运用json数组传输数据
  9. 一个号支持多个移动运营商
  10. Easy connect不能访问公网/外网/网页
  11. 各版本JQuery文件下载
  12. od另类调试php,[转] 另类基址搜索方法!好像是OD附加内存搜索工具 查找基址
  13. 小程序Dialog弹出窗
  14. bat批处理,变量不生效
  15. Python爬虫 selenium自动化 利用搜狗搜索爬取微信公众号文章信息
  16. 自动驾驶是一门怎样的生意?盘点5家创业公司商业落地的3条逻辑...
  17. JavaScript中方法或者变量名称前加下划线的是什么意思?
  18. HTML文本、段落标记
  19. 不知道O2O产品的APP该如何运营推广?
  20. ChatGPT 大规模封号。。。

热门文章

  1. 第七颗头骨 忘魂花 凤凰
  2. WebGL three.js 3D 场景
  3. 实验二 数字类型及其操作(新)
  4. C++ 实现文件分割、合并
  5. 用Python告诉你深圳房租有多高,做程序员真的能买得起嘛
  6. 基于开源软件打造企业网络安全
  7. 云原生KubeSphere DevOps流水线部署RuoyiCloud
  8. JS网页特效实例:动态关闭页面
  9. java 建造者模式的实际应用场景
  10. uvc和v4l2简介