hiho练习“Drinking Game"二分搜索

本文介绍了一种使用二分查找算法解决游戏策略问题的方法。通过定义一个函数f(T)来模拟玩家Ho在不同初始水量T下的得分,并利用二分查找确定使Ho赢得比赛所需的最小初始水量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eva_Hua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值