尺取
游标卡尺真好玩
尺取法
eMmmmm
适用条件 单调性,区间长度递增,sum递增
具体来说:对于判断条件k,区间长度递增,k也递增。
例如判断条件为区间和sum时,区间长度递增,sum也递增。
模板
优雅-永不过时
求最长不重复子串 xtu 1264
1
2
3
4
5
6
7
8ll l=0,maxl=0;
ll cnt[555];vector<string> ans;
memset(cnt,0,sizeof(cnt));
for(ll r=0;r<s.length();r++){
cnt[s[r]]++;
while(cnt[s[r]]>1) cnt[s[l++]]--;
maxl=max(maxl,r-l+1);
}求最短序列和>=k Subsequence POJ - 3061
1
2
3
4
5
6
7ll l=1,sum=0,ans=INF;
for(ll r=1;r<=n;r++){
sum+=val[r];
if(sum<k) continue;
while(sum>=k) sum-=val[l++];
ans=min(ans,r-l+2);
}
经典例题 最短子序列和>=s
题目链接 https://vjudge.net/problem/POJ-3061
题意 求一段最短的子序列之和>=s
思路 跑尺取即可
核心代码
1 | for(int i=0;i<n;i++){ |
灵活运用
题目链接 https://www.cnblogs.com/iiyiyi/p/5962512.html
题意 求一段含负数的子序列之和的绝对值最接近t,输出该段子序列之和及左右端点。
思路 与平常子序列之和不同的一点就是含有负数,如何处理负数的问题是关键。因为有负数,导致序列非单调,不能使用尺取法。所以我们需要转化一下,关键又是转化!!!所以我们可以发现这类题的关键都是转化一下数据形式,把数据处理成我们能处理的形式,即可!核心思路都是一样的!这里我们将其转化为前缀和,再将前缀和按升序排列即可跑尺取法了。
灵活运用-结合Hash
题目链接 https://vjudge.net/problem/POJ-3320
题意 求一段最短序列包含所有知识点,知识点用一个整数表示,范围是到2^32
思路 因为知识点范围很大,到2^32,所以我们需要将知识点Hash下,不然存不下,之后就是将知识点数量理解为尺取里的Sum即可。