浅谈尺取法

例题一:

http://acm.hdu.edu.cn/showproblem.php?pid=5056

题目大意翻译:

给你一个由小写字母组成的字符串,使得子串中每个小写字母的数目不超过k,你的任务是计算这样的子串的数目

分析:

枚举字符串下标i,每次计算以i为结尾的符合条件的最长串。

那么以i为结尾的符合条件子串个数就是最长串的长度。求和即可

现在考虑如何算以i结尾的最长串

好吧其实这就是个尺取法

聪明的你一定看了code就会的

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int Max= 100010;
char str[Max];
int vis[30];
int main()
{
    int k,T,len;
    LL sum;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",str);
        scanf("%d",&k);
        memset(vis,0,sizeof(vis));
        len = strlen(str);
        int l=0;sum=0;
        for(int i=0;i<len;i++)
        {
            vis[str[i]-'a']++;
            while(vis[str[i]-'a']>k)vis[str[l]-'a']--,l++;
            sum+=(i-l+1);

        }
       cout<<sum<<endl;
    }
    return 0;
}

例题二:

http://poj.org/problem?id=3061

题目大意:给出一个序列,求区间和大于或者等于S的最短区间长度的最小值

结合上一题,

还是考虑以i结尾的区间和大于等于S的区间长度的最小值

part code:

for (int l=1,r=0,now=0;l<=n;){
  while (now<S&&r<n) now+=a[++r]; //表示先把r+1,再执行now+=a[r].注意要使r<=n.
  /*当now<S的时候,我们不断地向右延伸区间,直到now>=S*/
  if (now<S) break;
  /*这时候l已经过大了,r到n也满足不了条件,这时要退出循环,否则下面的ans会被错误更新.*/
  ans=min(ans,r-l+1); // [l,r]区间的长度
  now-=a[l++]; // 这里就是先执行now-=a[l],然后再执行l+=1.
}

例题三:

https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=513&problem=2619&mosmsg=Submission+received+with+ID+11683193

题目大意:题目要求找到一个尽量长的连续序列,使得该序列中没有相同的元素

分析:

从左到右首先尽量延长right,right无法延长时再继续把left向右移动一个,然后重复以上过程,每次再取ans最大值即可。另外再判断重复时可采用数据结构,利用set集合十分方便


#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
 
#define maxn 1000005
int a[maxn];
set<int> s;
 
int main()
{
//	freopen("input.txt","r",stdin);
	int t,n;
	scanf("%d",&t);
	while(t--){
		s.clear();
		scanf("%d",&n);
		int i,l=0,r=0,ans=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		while(r<n){
			while(r<n&&!s.count(a[r])) s.insert(a[r++]);
			ans=max(ans,r-l);
			s.erase(a[l++]);
		}
		printf("%d
",ans);
	}
	return 0;
}

总之:

尺取法很简单,处理一些不定区间或子集问题

原文地址:https://www.cnblogs.com/wzxbeliever/p/11735405.html