一、尺取法 O(n)
问题类型:求取满足条件的最小区间的方法
算法描述:尺取法通常是指对数组保存一对下标(起点、终点),然后根据实际情况交替推进两个端点,直到得出答案。
e.g:POJ 3061
给定长度为n的数列和整数S,求出总和不小于s的连续子序列的长度的最小值
1)可预处理前缀和,再用二分来做O(nlog n)
2)尺取法,分别用 s 和 t 来指向选取的起点和终点
int s = 0, t = 0, sum = 0, ans = INF;
while(1){
while(t < n && sum < S){
sum += a[t];
t++;
}
if(sum < S) break;
ans = min(ans, t - s);
sum -= a[s];
s++;
}
if(ans == INF) cout << 0 << endl;
else cout << ans << endl;
e.g: POJ 3320
总结:尺取法使用条件:假设从 s 到 t 满足条件,那么从s+1开始,必须满足t’>= t