1052 地鼠游戏

题目描述 Description

王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不但学习刻苦,而且善于经常总结、完善自己的学习方法,所以他总能在每次考试中得到优异的分数,这一切很大程度上是由于他是一个追求效率的人。

但王钢也是一个喜欢玩的人,平时在学校学习他努力克制自己玩,可在星期天他却会抽一定的时间让自己玩一下,他的爸爸妈妈也比较信任他的学习能力和学习习惯,所以在星期天也不会象其他家长一样对他抓紧,而是允许他在星期天上午可以自由支配时间。

地鼠游戏是一项需要反应速度和敏捷判断力的游戏。游戏开始时,会在地板上一下子冒出很多地鼠来,然后等你用榔头去敲击这些地鼠,每个地鼠被敲击后,将会增加相应的游戏分值。问题是这些地鼠不会傻傻地等你去敲击,它总会在冒出一会时间后又钻到地板下面去(而且再也不上来),每个地鼠冒出后停留的时间可能是不同的,而且每个地鼠被敲击后增加的游戏分值也可能是不同,为了胜出,游戏参与者就必须根据每个地鼠的特性,有选择地尽快敲击一些地鼠,使得总的得分最大。

这个极具挑战性的游戏王钢特别喜欢,最近他经常在星期天上午玩这个游戏,慢慢地他不但敲击速度越来越快(敲击每个地鼠所需要的耗时是1秒),而且他还发现了游戏的一些特征,那就是每次游戏重新开始后,某个地鼠冒出来后停留的时间都是固定的,而且他记录了每个地鼠被敲击后将会增加的分值。于是,他在每次游戏开始后总能有次序地选择敲击不同的地鼠,保证每次得到最大的总分值。

输入描述 Input Description

输入包含3行,第一行包含一个整数n(1<=n<=100)表示有n个地鼠从地上冒出来,第二行n个用空格分隔的整数表示每个地鼠冒出后停留的时间,第三行n个用空格分隔的整数表示每个地鼠被敲击后会增加的分值(<=100)。每行中第i个数都表示第i个地鼠的信息。

输出描述 Output Description

输出只有一行一个整数,表示王钢所能获得的最大游戏总分值。

样例输入 Sample Input

5

5  3  6  1  4

7  9  2  1  5

样例输出 Sample Output

24

贪心+并查集

我们先假设每个地鼠都在冒出的最后一秒被打,数组hit[i]=j,表示第i秒打第j个地鼠。并查集数组fa[i]=k,裸并查集表示的是i的父亲是k,在这儿表示从第i秒往前,第一个可以打地鼠的时间。

以输入数据:

3

5 5 5

1 2 3

为例,表示有3只地鼠停留时间都是5秒。

所以就枚举每一个地鼠,只要他的fa不为0,就代表是要打的地鼠,加上它的分值,最后输出。

这样就产生了一个问题,题目要求输出最大值,而我们在枚举过程中并没有去比较谁打谁小,只要fa[]值不为0,就打。所以有人就会有疑问了,这样能保证我不打的地鼠一定比我要打的地鼠分值少吗?

答案是不能保证。

大家注意一下,我题解最开头写的是贪心+并查集,并查集部分有了,那贪心在哪?

这就是本题正确与否的关键。

想一下。如果我们能保证我后面枚举的地鼠的分值,一定小于前面枚举的地鼠的分值,那不就解决了这个问题吗?只要后枚举的地鼠分值更小,不管打不打,都不会是最优答案。所以在并查集之前,先将所有的分值从大到小排一次序,贪心贪的是分高的。

还有,在此过程中我们可以发现hit数组除了显示哪一秒打哪个地鼠外,根本没有用。而题目只需要输出分值,所以可以把hit数组去掉,前面加上是为了方便大家理解。

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int n,s,fa[],ans;
struct node
{
int time,grade;
}e[];
bool cmp(node p,node q)
{
return p.grade>q.grade;
}
int find(int i)//并查集查找模板
{
if(fa[i]!=i) fa[i]=find(fa[i]);
return fa[i];
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&e[i].time);
for(int i=;i<=n;i++) scanf("%d",&e[i].grade);
sort(e+,e+n+,cmp);//排序
for(int i=;i<=;i++) fa[i]=i;//并查集初始化
for(int i=;i<=n;i++)//枚举每一个地鼠
{
int r=find(e[i].time);//找到他的父亲,也就是从这一秒往前第一个可以打地鼠的时间
if(r)//r=0表示不能打了
{
fa[r]=find(fa[r-]);
ans+=e[i].grade;
}
}
printf("%d",ans);
}

最新文章

  1. Java数据结构与算法之---求两个数的最大公约数(欧几里得算法)
  2. Unity3D Sprite Draw Call合批规则
  3. GOF业务场景的设计模式-----责任链模式
  4. C#学校班级自动升级实现代码
  5. SQL语句中如何把文件以二进制数组形式存入数据库
  6. 哈哈,好像swift 以后有可能用来开发安卓喔
  7. ZOJ 1201 Inversion
  8. 《The Google File System》论文阅读笔记——GFS设计原理
  9. snprintf 返回值
  10. mongo数据库使用小结
  11. Lecture Halls
  12. Android学习总结——Service组件
  13. c语言捕捉异常
  14. msgid 属性
  15. linux 下 eclipse 安装
  16. 006-Redis 发布订阅
  17. jQuery插件实例二:年华时代插件ReturnTop回到首页
  18. Ubuntu 12.04 root用户登录设置
  19. 1.初步认识JVM -- JVM序列
  20. python中nltk的下载安装方式

热门文章

  1. 2015游戏蛮牛——蛮牛杯第四届开发者大赛 创见VR未来开启报名
  2. Python爬虫小白入门(一)写在前面
  3. .Net语言 APP开发平台——Smobiler学习日志:如何实现离线声音文件上传
  4. Mybatis常用总结:参数,返回,执行sql,include等
  5. [连载]《C#通讯(串口和网络)框架的设计与实现》- 13.中英文版本切换设计
  6. Eclipse(一)
  7. Java操作wkhtmltopdf实现Html转PDF
  8. SQLServer修改表字段名称
  9. JS eval()函数的一些见解
  10. ES6之数组扩展方法【一】(相当好用)