多重背包二进制优化(wzk吃小鸡腿)
问题 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吃小鸡腿)相关推荐
- [多重背包+二进制优化]HDU1059 Dividing
题目链接 题目大意: 两个人要把一堆宝珠,在不能切割的情况下按照价值平分,他们把宝珠分成6种价值,每种价值的宝珠n个. n<=200000 思考: 首先如果加和下来的价值是一个偶数 那么还分毛啊 ...
- HDU 5445 Food Problem 多重背包+二进制优化
据说也可以用单调队列优化多重背包,但是我不会,所以还是选择了二进制优化... 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:先给n,m, ...
- POJ 1014 Dividing【多重背包+二进制优化】
大意: 价值1, 2, 3, --, 6的物品分别a1, a2, --, a5, a6件 问能否把这些物品分成两份,使其具有相同的价值(所有物品必须全部用上) 分析: 给个物品有多件,即多重背包 只要 ...
- zcmu-1919: kirito(多重背包——二进制优化)
Description 主角kirito是使用世界首款完全潜行游戏"刀剑神域(Sword Art Online)"的玩家.曾经很幸运的参与过封闭测试,并买下正式版的kirito,正 ...
- Dividing(多重背包二进制优化)
题意:有价值为1-6的六种玻璃球,现在告诉你各种玻璃球的个数,问能否将这些玻璃球分成两份,使得两份的总价值相等 既然要等分,那么总价值必定是偶数,所以价值和为奇数是无法等分. 但价值和为偶数时,我们可 ...
- 12.14补卡,多重背包二进制优化
题目链接:22背包专题 [Cloned] - Virtual Judge (vjudge.net) 思路:多重背包的主要思路就是把每一个物品分开放,从而达到每个物品拿与不拿全部遍历到.但是当物品数量过 ...
- hdu2844 Coins(普通的多重背包 + 二进制优化)
看完背包九讲的多重背包之后,这题目应该可以轻松做出来了 模型: 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的 ...
- ZCMU-1919 kirito's 星爆气流斩(多重背包+二进制优化)
Problem C: kirito's 星爆气流斩 Time Limit: 2 Sec Memory Limit: 128 MB Submit: 148 Solved: 37 [Submit][S ...
- ZCMU 1919: kirito's 星爆气流斩(多重背包+二进制优化)
1919: kirito's 星爆气流斩 Time Limit: 2 Sec Memory Limit: 128 MB Description 主角kirito是使用世界首款完全潜行游戏" ...
- hdu 2191 (多重背包二进制优化)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 实现代码: #include<bits/stdc++.h> using namespac ...
最新文章
- spring YML属性提示
- java中ofd文件转pdf_word文件转pdf怎么转?这一招轻松搞定Word转PDF
- Mysql优化(三):优化order by
- clientWidth、clientHeight、offsetWidth、offsetHeight以及scrollWidth、scrollHeight
- CSS 背景尺寸 background-size属性
- windows server 2008 - 隐藏磁盘分区 (2)
- Way to MongoDB
- Ajax运用json数组传输数据
- 一个号支持多个移动运营商
- Easy connect不能访问公网/外网/网页
- 各版本JQuery文件下载
- od另类调试php,[转] 另类基址搜索方法!好像是OD附加内存搜索工具 查找基址
- 小程序Dialog弹出窗
- bat批处理,变量不生效
- Python爬虫 selenium自动化 利用搜狗搜索爬取微信公众号文章信息
- 自动驾驶是一门怎样的生意?盘点5家创业公司商业落地的3条逻辑...
- JavaScript中方法或者变量名称前加下划线的是什么意思?
- HTML文本、段落标记
- 不知道O2O产品的APP该如何运营推广?
- ChatGPT 大规模封号。。。