您的位置:首页 > 其它

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)

而要证明
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>



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: