尺取法

尺取法的整个过程分为4部:

1.初始化左右端点

2.不断扩大右端点,直到满足条件

3.如果第二步中无法满足条件,则终止,否则更新结果

4.将左端点扩大1,然后回到第二步

返回的推进区间开头和结尾,求满足条件的最小区间的方法称为尺取法。

参考博客:尺取法枚举区间
尺取法 — 详解 + 例题模板(全)

例:Poj3061

题意:给定一个序列,使得其和大于或等于S,求最短的子序列长度。

分析:首先,序列都是正数,如果一个区间其和大于等于S了,那么不需要在向后推进右端点了,因为其和也肯定大于等于S但长度更长,所以,当区间和小于S时右端点向右移动,和大于等于S时,左端点向右移动以进一步找到最短的区间,如果右端点移动到区间末尾其和还不大于等于S,结束区间的枚举。

这个题目区间和明显是有趋势的:单调变化,所以根据题目要求很容易求解,但是在使用之间需要对区间前缀和进行预处理计算。

代码:


#include <cstdio>  
#include <algorithm>  
#include <cstring>  
#define MAX 100005  
#define LL long long  
#define INF 0x3f3f3f3f  
  
using namespace std;  
LL a[100010];  
int n, t, ans = INF;  
LL sum, s;  
  
int main()  
{  
    scanf("%d", &t);  
    while (t--){  
        scanf("%d %I64d", &n, &s);  
        for (int i = 0; i < n; i++) scanf("%I64d", a+i);  
        int st = 0, en = 0;  
        ans = INF; sum = 0;  
        while (1){  
            while (en<n && sum<s) sum += a[en++];  
            if (sum < s) break;  
            ans = min(ans, en-st);  
            sum -= a[st++];  
        }  
        if (ans == INF) ans = 0;  
        printf("%d\n", ans);  
    }  
    return 0;  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值