Bamboo&APTX4844魔发药水

题意

“于是,Bamboo耐着性子,看巫师从袖子里掏出 M 瓶时光泉水和 K 粒绿色能量。每瓶时光泉水重量为 c ,生发效果为 l;每粒绿色能量的重量为w ,生发效果为 r。但一瓶APTX4844的重量不能超过 S,否则很难过安检(难道不是难以下咽?)。”  

“配置魔发药水需要用到至多两种原料:固态的绿色能量和液态的时光泉水。但是由于两者副作用不一样,*制作时优先选用副作用小的绿色能量,即先考虑使用绿色能量使得生发效果最大,然后再考虑时光泉水。*”

“Bamboo准备制作一瓶APTX4844试试效果,**同时力求达到最好的生发效果**,所以可以得到的最佳生发效果为多少?”

“绿色能量一个就是一个,单个为最小单位,不要有其他想法。但是瓶装时光泉水是液体,用不完一瓶可以以后用啊”

所以这里想表达的是,在副作用最小的情况下,使得生发效果最好。这不是一个合起来求最优生发效果的题,这是个有条件的最优,也可看作两道题,一个是01背包,一个是分数背包。贪心的求了两者的最大值。

多重背包为什么不对

如果采用多重背包的方式,也是考虑了性价比的问题(效果除以重量),但是其实是在试图求解全局最优,而不是条件最优,这种做法是没有看到要“优先使用绿色能量”,也就是能选则选。其实是以性价比为价值,一瓶一瓶的挑选时光泉水。(至于副作用什么的,只是为了表达优先选绿色能量编了个理由,因为也没有数据是具体涉及到副作用有多大之类的。 )如果还是觉得自己的多重背包可以选出符合题意的,可以看一组简单数据:

3 2 7
2 1
4 1
3 2
2 2
3 1

按照题目意思会先选绿色能量 2 2 和3 1,因为能选绿色能量就选嘛,装不下那没办法,此时背包里已经装了重量为5,效果为3的能量,还有剩余2单位重量可装时光泉水,选择最优的话其实是看“性价比”,也就是价值除以重量,可以在单位重量内达到最大的效果,也就是贪心的思想。那么按性价比排序后选择3 2时光泉水,但是并不是w重的整瓶都能装下,所以用时光泉水填满背包后增加的效果为 2 * (2/3)=1.33333,最后得到的结果就是3+1.333=4.3

而多重背包得到的答案是5.0,比4.3这个值还要高,实际是因为没有“优先”去选择绿色能量,而是只求最佳生发效果。

综上题目是01+分数背包,比赛时的两份数据不够随机,所以有多重背包的同学莫名其妙的过了…….

还有0.9的同学,可能的原因是当时有0 0 的边界情况应该结果是0.0;还有是绿色能量都装不下但是可以装时光泉水的错误输出了0.0

但是这道题按照题意先绿色能量后多重背包取液体的,也是可以的,因为给的数据均为整数,可以看作一份一份取液体

分数背包

下面来说分数背包:(第三版《算法导论》P243 贪心算法原理中 贪心VS动态规划 特意举了这个例子):

01背包:小偷偷东西,一个物品要么完整的拿走,要么不拿,不能只拿走物品的一部分

分数背包:设定基本一样,但是一个物品可以拿走一部分,而不是只做二元(拿与不拿)的选择,可以将物品想象成液体啊流体啊,比如金砂一类

其实两个背包都有最优子结构性质,但是贪心可以解决分数背包,而不能解决01背包。对分数背包,先计算出每个物品的每单位的价值,遵循贪心策略,小偷首先会尽量多的拿每磅价值最高的物品,如果该物品全部拿走而背包没满,就再尽量多的选择每磅价值第二高的物品,依次类推,直到达到背包重量上限。按物品每磅价值排序,复杂度可以到 O(nlgn)

至于为什么贪心不能算01背包,自行看《算法导论》中的例子

回到本题

为了不杂糅起来引发意想不到的逻辑问题,所以安排了前后顺序

绿色能量是要么完整取,要么不用的0-1背包(什么?不是优先用绿色能量吗怎么还不用?。。背包装不下自然就不选了)

现在只用绿色能量已经求到最大值了,但是背包还没满啊,那再加点时光泉水岂不是生发效果会更好?时光泉水用不用用多少都行,这是一个分数背包的问题,求出此时剩余的容量,贪心的装满就好了!

只保留一位小数,所以可能精度不会有很大问题

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxx = 1e5+1;
int w,r;
int dp[maxx];//for green energy only
int weight[maxx];
struct water{
double c,I;
double rate;
}wa[maxx];
bool cmp(water a, water b)
{
return a.rate>b.rate;
}
int main()
{
int M,K,S,i,j;
while(cin>>M>>K>>S)
{
memset(dp,0,sizeof(dp));
memset(weight,0,sizeof(weight));
for(i=0;i<M;i++)
{scanf("%lf %lf",&wa[i].c,&wa[i].I);
wa[i].rate = wa[i].I/wa[i].c;
}
for(i = 0;i<K;i++){
scanf("%d %d",&w,&r);
for(j = S;j>=w;j--)
if(dp[j]<dp[j-w]+r)
{dp[j]=dp[j-w]+r;
weight[j]=weight[j-w]+w;
}
}
int rem = S - weight[S];
int nowValue = dp[S];
double price = 0.0;
// 贪 心
if(rem>0)
{
sort(wa,wa+M,cmp); double drem = (double)rem;
for(i = 0;i<M;i++)
{
if(drem>=wa[i].c)
{
price+=wa[i].I;
drem-=wa[i].c;
}
else if(drem>0&&drem<wa[i].c)
{
price+=wa[i].rate*drem;
drem = 0;
} if(drem == 0)break;
}
}
double ans = (double)nowValue + price;
printf("%.1lf\n",ans);
}

传送门

很震惊,似乎大家没怎么看到书上这个分数背包,附上oj上一道专门的分数背包问题,想必看完上面的解题报告应该知道怎么求解分数背包了

2016级算法第五次上机-B.Bamboo&APTX4844魔发药水的更多相关文章

  1. 2016级算法第五次上机-C.Bamboo和"Coco"

    1064 Bamboo和"Coco" 分析题意 每个亡灵至少一个花瓣,相邻的亡灵中思念值高的要获得的花瓣高(思念值相等是不需要花瓣一样多的).主要考贪心思路,为了使得花瓣总量最少, ...

  2. 2016级算法第五次上机-F.ModricWang的水系法术

    1066 ModricWang的水系法术 思路 比较典型的最大流问题,需要注意的是,题目已经暗示(明示)了这里的边是双向的,在建图的时候需要加上反向边的容量值. 解决最大流问题的基本思路就是不断在残量 ...

  3. 2016级算法第五次上机-E.AlvinZH的学霸养成记IV

    1039 AlvinZH的学霸养成记IV 思路 难题,最大二分图匹配. 难点在于如何转化问题,n对n,一个只能攻击一个,判断是否存在一种攻击方案我方不死团灭对方.可以想到把所有随从看作点,对于可攻击的 ...

  4. 2016级算法第五次上机-A.Beihang Collegiate Pronunciation Contest 2017

    1065 Beihang Collegiate Pronunciation Contest 2017 思路 在字符串中不断做匹配 找到一个匹配就输出 时间复杂度\(O(n)\) ps.模式串是定长的, ...

  5. 2016级算法第五次上机-G.ModricWang的撒币游戏

    1062 ModricWang的撒币游戏 思路 此题为2017年ACM-ICPC亚洲区域赛乌鲁木齐赛区的A题,现场94个队中有38个队做出此题.在这里作为满分以外的题,是为了让大家看一下外面一些题的风 ...

  6. 2016级算法第五次上机-D.AlvinZH的学霸养成记III

    850 AlvinZH的学霸养成记III 思路 难题.概率DP. 第一种思考方式:直接DP dp[i]:从已经有i个学霸到所有人变成学霸的期望. 那么答案为dp[1],需要从后往前逆推.对于某一天,有 ...

  7. 2016级算法第六次上机-E.Bamboo之吃我一拳

    Bamboo之吃我一拳 分析 当两个点的距离<=d时,才可以出拳,想要使得满足出拳条件的点对最少但不为0 寻找最近点对距离,得到的最近距离能够使得可以出拳的组数最少,因为除了最近点对外其他组合均 ...

  8. 2016级算法第六次上机-A.Bamboo之寻找小金刚

    Bamboo之寻找小金刚 分析 可以抽象为许多连续线段,分别计数左拐和右拐的个数.考察叉积的基础应用. 假设ABC三点构成一个夹角∠ABC,B就是拐点,AC是辅助形成夹角.考虑线段AB和BC形成的向量 ...

  9. 2016级算法第四次上机-E.Bamboo and the Ancient Spell

    Bamboo and the Ancient Spell 分析 可能英文读题难度比较大,但是只要看到全大写的 "THE LONGEST COMMON SUBSEQUENCE !"应 ...

随机推荐

  1. 快速求出n!的质因数的个数

    一般做组合数的题目都要进行质因数的分解,我们一般是for循环对每个数进行质因数分解,大多数情况都不会超时,但极少数的情况下,题目会不允许这样的做法,所以我们需要学会一种更快的方法来求质因数. 我们一般 ...

  2. CNN和GAN 比较nice的介绍

    CNN是个什么鬼:https://www.zhihu.com/question/52668301 就是这样GAN : https://zhuanlan.zhihu.com/p/27199954

  3. unittest测试框架详谈及实操(四)

    测试套件 应用unittest的Test Suite特性,可以将不同的测试组成一个逻辑组,然后设置统一的测试套来一起执行测试.通过TestSuite.TestLoader类来创建测试套件,最后用Tes ...

  4. 团体程序设计天梯赛L2-003 月饼 2017-03-22 18:17 42人阅读 评论(0) 收藏

    L2-003. 月饼 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不 ...

  5. 设计模式11---组合模式(Composite Pattern)

    一.组合模式定义 将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性.Compose objects into tree structures to re ...

  6. 使用 JAVA 中的动态代理实现数据库连接池

    数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈.我们可以在互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个共 ...

  7. NYTimes Objective-C 编程风格指南

    转自eseedo的博客   [微博] NYTimes Objective-C 编程风格指南.来源:https://github.com/NYTimes/objective-c-style-guide ...

  8. VS2010 solution中完美的相对路径引用方法

    假设您有一个工程叫solar,路径结构是这样的: 公用头路径: d:\solar\public\include公用库路径:d:\solar\public\libmars项目 : d:\solar\ma ...

  9. [转发]Oauth 1.0 1.0a 和 2.0 的之间的区别有哪些?

    原文地址:http://www.zhihu.com/question/19851243

  10. 在ie6下将png24图片透明

    没想到IETester中IE6和IE6真实版本不一样...之前一直没有实现png图片的透明度,现在发现原来是版本不一样惹的祸.总之,我将解决方法以demo的方式显示出来,以供再次利用. <!DO ...