二分答案:跳石头
题目:P2678 [NOIP 2015 提高组] 跳石头 - 洛谷
跳石头这道题!表面上看着简单,但耗费了我太多时间了!
细节点:
- 不要忘记起点和终点 a[0] = 0; a[N+1] = L;
- 最大跳跃长度是起点到终点,right最大设置成L
- calc的计算容易出错
calc的计算:
- 设置 j = i+1;
- 当 j 符合范围并且 可以跳跃时,j++。j往前跳就行了,i原地不动。
- 跳出while循环,计算移走的石头时不要忘记-1
- 更新i
#include <iostream>using namespace std;
typedef long long LL;
const int n = 5e4 + 10; LL L, N, M, mid;
LL a[n];LL calc(LL x)
{LL ret = 0;for (int i = 0; i <= N; i++){int j = i+1;while(j <= N+1 && a[j]-a[i] < x) j++;ret += j-i-1;i = j-1;}return ret;
}int main()
{cin >> L >> N >> M;//求跳跃距离的最大值for (int i = 1; i <= N; i++) cin >> a[i];a[0] = 0;a[N+1] = L;//起点和终点的距离 LL left = 0, right = L;while(left < right){mid = (left+right+1)/2;if (calc(mid) > M) right = mid-1;else left = mid; } if (calc(left) > M ) cout << 0 << endl;else cout << left << endl;return 0;
}
结合洛谷砍树,木材加工,跳石头这三道题。我们可以发现二分答案的使用场景有共同点:
问题类型:最优化问题中的极值问题
- 共同特征:都是要求最大化最小值或最小化最大值的问题
- 答案在明确区间范围内
答案的单调性
如果值X满足条件,那么所有小于X的值(对于最大化问题)或所有大于X的值(对于最小化问题)也满足条件 |
反之,如果值X不满足条件,那么所有大于X的值(对于最大化问题)或所有小于X的值(对于最小化问题)也不满足条件 |