hihoCoder之hiho一下 第六十九周 解题
2015-10-25 21:42
393 查看
题目1 : HIHODrinking Game
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
Little Hi and Little Ho are playing adrinking game called HIHO. The game comprises N rounds. Each round, Little Hipours
T milliliter of water into Little Ho's cup then Little Ho rolls a K-facesdice to get a random number d among 1 to K. If the remaining water in LittleHo's cup is less than or equal to d milliliter Little Hi gets one score andLittle Ho drinks up the remaining
water, otherwise Little Ho gets one score andLittle Ho drinks exactly d milliliter of water from his cup. After N rounds whohas the most scores wins.Here comes the problem. If Little Ho can predict thenumber d of N rounds in the game what is the minimum value
of T that makesLittle Ho the winner? You may assume that no matter how much water is added, LittleHo's cup would never be full.
输入The firstline contains N(1 <= N <= 100000, N is odd) and K(1 <= K <=100000).The
second line contains N numbers, Little Ho's predicted number d of Nrounds.
输出Output theminimum value of T that makes Little Ho the winner.
样例输入
5 6
3 6 6 2 1
样例输出
4
解题思路:
该题的目的是要求取出最小的T,并且K的序列以及得分的规则是已知的。因而可以很容易写出每一个轮回中Ho的得分情况。本题中需要让Ho胜出,总分显然是N(N为奇数),因此,只需要Ho的得分大于N/2即可。在本题的难点主要在于对算法复杂度的要求,如果采取暴力求解,即T的范围锁定在K序列的最小值min,最大值max+1之间,即T的范围为[min,max+1]。采取这种暴力求解的方式,固然可以求解出来,但是此时计算复杂度较高。因此暴力求解并不是好的方法。这时,我们希望能最好找到得分score与T之间的一个关系。很明显的有当T=0时,score=0。当T=max+1时,有score=N。因此,可以猜想score与T之间是否是存在一个单调递增的关系。
因此,可以假设:
score = f(T)
而要证明
我们设
我们要证明:对于
利用数学归纳法,
假设
由于
当
当
当
综上所述,对于
得到
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
Little Hi and Little Ho are playing adrinking game called HIHO. The game comprises N rounds. Each round, Little Hipours
T milliliter of water into Little Ho's cup then Little Ho rolls a K-facesdice to get a random number d among 1 to K. If the remaining water in LittleHo's cup is less than or equal to d milliliter Little Hi gets one score andLittle Ho drinks up the remaining
water, otherwise Little Ho gets one score andLittle Ho drinks exactly d milliliter of water from his cup. After N rounds whohas the most scores wins.Here comes the problem. If Little Ho can predict thenumber d of N rounds in the game what is the minimum value
of T that makesLittle Ho the winner? You may assume that no matter how much water is added, LittleHo's cup would never be full.
输入The firstline contains N(1 <= N <= 100000, N is odd) and K(1 <= K <=100000).The
second line contains N numbers, Little Ho's predicted number d of Nrounds.
输出Output theminimum value of T that makes Little Ho the winner.
样例输入
5 6
3 6 6 2 1
样例输出
4
解题思路:
该题的目的是要求取出最小的T,并且K的序列以及得分的规则是已知的。因而可以很容易写出每一个轮回中Ho的得分情况。本题中需要让Ho胜出,总分显然是N(N为奇数),因此,只需要Ho的得分大于N/2即可。在本题的难点主要在于对算法复杂度的要求,如果采取暴力求解,即T的范围锁定在K序列的最小值min,最大值max+1之间,即T的范围为[min,max+1]。采取这种暴力求解的方式,固然可以求解出来,但是此时计算复杂度较高。因此暴力求解并不是好的方法。这时,我们希望能最好找到得分score与T之间的一个关系。很明显的有当T=0时,score=0。当T=max+1时,有score=N。因此,可以猜想score与T之间是否是存在一个单调递增的关系。
因此,可以假设:
score = f(T)
而要证明
f(T)函数确实满足递增的性质,只需证明对于 T 和 T' (T < T'),每一轮开始时小Ho的得分和剩余的饮料体积,T 对应的数值都不超过 T' 对应的数值。
我们设
s[i],
r[i]表示第i轮开始,还没有添加 T 单位饮料时,小Ho的得分和剩余饮料的体积;
s'[i],
r'[i]表示第i轮开始,还没有添加 T' 单位饮料时,小Ho的得分和剩余饮料的体积。
我们要证明:对于
i= 1..N+1,都有
s[i] ≤ s'[i]且
r[i] ≤ r'[i]。
利用数学归纳法,
i= 1 时,
s[i] = s'[i] = 0,
r[i] = r'[i] = 0,结论成立。
假设
i= n 时结论成立,那么当
i= n+1 时:
r[n+1] = max(r +T-d, 0),
r'[n+1] = max(r' +T'-d, 0)。
由于
r ≤ r',T < T',所以
r +T < r' +T'
当
d < r +T < r' +T时,
r[n+1] = r +T-d,
r'[n+1] = r' +T'-d,
s[n+1] = s +1,
s'[n+1] = s' +1,易知结论成立;
当
r +T ≤ d < r' +T时,
r[n+1] = 0,
r'[n+1] = r' +T'-d > 0,
s[n+1] = s,
s'[n+1] = s' +1,易知结论成立;
当
r +T < r' +T ≤ d时,
r[n+1] = r' = 0,
s[n+1] = s,
s'[n+1] = s',易知结论成立。
综上所述,对于
i= 1..N+1,都有
s[i] ≤ s'[i]且
r[i] ≤ r'[i]。而
f(T) = s[N+1] ≤ s'[N+1] = f(T'),所以函数
f(T)是单调递增的。
得到
f(T)是单调递增的,那么,我们就可以用二分法求解了,这样算法复杂度降低很多。
<span style="color:#333333;">#include<iostream> using namespace std; int main(){ int N; int K; int T; int flag=0; cin>>N>>K; int d[100000]={0}; int min=100000; int max=0; int mid=0; for(int i=0;i<N;i++){ cin>>d[i]; if(min>d[i]) min=d[i]; if(max<d[i]) max=d[i]; } if(min==max){ //</span><span style="color:#ff0000;">此处需要注意,当出现min与max相同时,是不会进入while循环的,此时T</span><span style="color:#333333;"> max++; //</span><span style="color:#ff0000;">应为max+1</span><span style="color:#333333;"> T=max; } else{ max++; while(min+1<max){ mid=(min+max)/2; T=mid; int score_O=0; int height=0; for(int i=0;i<N;i++){ height+=T; if(height<=d[i]){ height=0; } else{ score_O++; height-=d[i]; } } if(score_O<=N/2){ min=mid; } else{ max=mid; } } } T=max; cout<<T; return 0; //delete []d; }</span>
相关文章推荐
- 更改git bash默认的路径
- SQLite学习笔记(七)&&事务处理
- UML之用例图
- poj-2492 -A Bug's Life-并查集的使用
- Struts2基于XML配置文件实现输入校验
- perl - 单引号和双引号字符串
- ORACLE数据库异步IO介绍
- JAVA课后作业
- 第七周
- 【SSSP】A forward-backward single-source paths algorithm
- 待更正
- 特别码字
- 百度贴吧推广需要注意的几个技巧分析
- 拒绝OOM,打造自定义帧动画
- 读者写者问题--使用信号量的读者优先与写者优先程序分析
- 《软件需求模式》阅读笔记二
- Pitcher Rotation
- WordPress用户导入Drupal7并登录
- xcode7、iOS9 设置启动图片(Launch Image)
- 【小白装系统】——BIOS简介