尺取法是一种比较基础的算法,一般用来解决具有单调性的区间问题。通常是对数组保存一对下标,即所取的区间的左右端点,然后根据实际情况不断地推进左右端点以得出答案。
尺取法比直接暴力枚举区间的效率高很多,尤其是数据大的时候,所以说尺取法是一种高效的枚举区间的方法,是一种技巧,一般用于求取有一定限制的区间个数或最短的区间等等。
经典例题:
Poj3061
Subsequence
给定长度为n的数列整数a0,a1,...an-1以及整数s。求出总和不小于s的连续子序列的长度的最小值。如果不存在,则输出0。
样例1:
输入
10 15
5 1 3 5 10 7 4 9 2 8
输出
2
样例2:
输入:
5 11
1 2 3 4 5
输出:
3
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define ll long long
int main()
{
ll t,n,s,a[10000];
cin>>t;
while(t--)
{
ll sum=0;
cin>>n>>s;
for(ll i=0; i<n; i++)
{
cin>>a[i];
sum+=a[i];
}
if(sum<s)
cout<<0<<'\n';
else
{
sum=0;
ll l=0,r=0,ans=n+1;
while(1)//这样他会一直循环,除非写break等语句让他停止
{
while(sum<s&&r<n)
sum+=a[r++];
if(sum<s)
break;
ans=min(ans,r-l);//找最小字串的长度
sum-=a[l++];
}
cout<<ans<<'\n';
}
}
return 0;
}
//这个题要是用枚举的话得双重循环就会超时
类似题:
P1638逛画展
P2698[USACO12MAR]Flowerpot S
P2564[SCOI2009]生日礼物