hiho练习“Drinking Game"二分搜索

hiho讨论区有关于这个问题求解思路的非常详细的解释,我只记录下处理这类问题的自己的一点思路想法。


一:题目求解思路

1,题目求解:T最小多少的时候,Ho会赢,写成式子就是,求 min T 使得f(T)=score>N/2 (N是总比赛轮数),这个优化问题有以下两点要思考。

1)f(T)=score,这个函数如何实现?

int f(int T, vector<int> D)
{
int rest = 0; //每局开始水量
int score = 0;//每局开始分数
for (int i = 0; i != D.size(); i++)
{
rest = rest + T;
if (rest>D.at(i))
{
score = score + 1;
rest = rest - D.at(i);
}
else
{
rest = 0;
}
}
return score;
}

2)最小T怎么求?

假设T为0,则ho肯定输,0分;假设T无穷大,ho肯定赢,满分。由这个分析,我们可以猜想,是不是随着T增大score也在增大,

(假设该猜想成立,说明函数递增,这样顺序排序的搜索问题就可以用二分查找,时间复杂度O(lg(N)),反之,如果该猜想不成立,只能用从小到大的枚举法才能保证求解正确,时间复杂度O(N))

值得高兴的是,这个函数确实是单调递增的,证明很简单,数学归纳法。

二分查找程序如下:

int left = 0;
int right = K+1;
while (left+1<right)   //二分查找步骤,当left+1=right,说明程序查找结束
{
mid = (left + right) / 2 ;
if (f(mid, testD)>N/2)  
{
right = mid;   //如果中间测试值得分大于N/2,说明待求的T肯定在left~mid之间,所以更新上限right,否则更新下限left
}
else
{
left = mid;
}
}



猜你喜欢

转载自blog.csdn.net/whatwho_518/article/details/51167003
今日推荐