引入
二分查找想必大家一定都不陌生吧,就那个lower_bound(误;
当我们不太容易找到一个答案,但是能比较容易判断一个答案是否正确的时候,我们会想到怎么去解决只一个问题呢?非常好!枚举!
例题
暴力写法
洛谷的一道例题;在这道题中, 我们不太容易直接求出最小的距离是多少,但是我们可以判断出一个距离d是否可以通过移走m个石头做到,请看判断的代码:
bool check(int d)
{
int total = 0;
int l = 0, r = 1;
while (l <= r && r <= n + 1)
{
if (s[r] - s[l] < d)
total++, r++;
else
l = r, r++;
if (total > m)
return false;
}
return true;
}
我们可以在通过从大到小枚举每一个可能的d,就可以找出来最小的距离了:
for (int i = l; i >= 1; i--)
if (check(i))
{
cout << i;
return ;
}
但是根据题目所给的条件,会发现l <= 1e9,会TLE;
优化
二分答案的一个显著特征是比较容易判断一个答案是否满足条件,例如这道题的check函数–>代表了答案具有有界性;二分答案的另一个显著特征就是最大值最小或者最小值最大–>代表了答案具有单调性,因为x成立的话x+1也一定成立(类似这种的);
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> l >> n >> m;
for (int i = 1; i <= n; i++)
cin >> s[i];
s[n + 1] = l;
int left = 1, right = l, mid;
while (left < right)
{
mid = left + right + 1 >> 1;
if (check(mid))
left = mid;
else
right = mid - 1;
}
cout << left;
return 0;
}
4268

被折叠的 条评论
为什么被折叠?



