zoukankan      html  css  js  c++  java
  • 尺取法

    尺取法

    尺取法核心思路

    尺取法其实也是一种模拟,是解决寻找区间和问题的一种方法。

    假如有这么一个问题:给你一些数,请在这些数中找到一个区间,使得区间里每一个元素的和大于或等于给定的某个值。

    不会尺取法的话,肯定就会开双重循环,枚举区间起点和终点,然后每一次都求一次和,再和给定的数作比较。

    尺取法与它的思路类似,都是寻找一个区间的起点和终点。做法是:

    用两个指针,最初都指向,这一组数中的第一个,然后如果这个区间的元素之和小于给定的数,就把右指针向右移,直到区间和大于等于给定的值为止。之后把左指针向右移,直到区间和等于给定的值为止,保存方案,继续操作。

    假如左指针指向这些数的第一个,并且右指针指向这组数的最后一个,这种情况下的子区间元素之和仍然小于给定的数的话,那么就输出-1,表示不可能。

    那么怎么求区间和呢?

    当然,for一遍是可以的,但是太浪费时间了。我们可以引入一个累加器,初始值等于这组数中的第一个元素(因为最开始左指针和右指针都指向它),当右指针向右移时,累加器每次就加上右指针指向的元素的值。当左指针向右移时,累加器每次就减去左指针指向的值。

    怎么实现呢?

    实现

    这里有道模板题

    poj3061

    下面附上代码(不是我写的)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int a[100000+33];
    int ans,S,N;
    
    void solve()
    {
        ans=100000+44; 
        int L=1,R=1,sum=0,lsub=0;
        while(R<=N)
        {
            while(sum<S&&R<=N)//R总指向当前满足要求区间的下一个 注意此处R可能>N 
            {
                sum+=a[R];//累加器加上右指针指向的元素
                ++R;//右指针向右移
                ++lsub;
            }
            while(sum>=S)//L总指向当前区间的最左边  左闭右开 
            {
                sum-=a[L];//累加器减去左指针指向的元素的值
                ++L;//左指针右移
                --lsub;
            }
            ans=min(ans,lsub+1);
        }
    }
    
    int main()
    {
        int T,i,sum;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d %d",&N,&S);
            sum=0; bool flag=false;
            for(i=1;i<=N;++i) 
            {
                scanf("%d",&a[i]);
                sum+=a[i];
                if(sum>=S&&!flag) flag=true;    
            }
            if(!flag)
            {
                printf("0
    "); continue;
            }
            solve();
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    尺取法嘛。。应该很好懂,就是一种模拟的策略。

  • 相关阅读:
    poj 1286
    poj 1815
    poj 3368
    十个利用矩阵乘法解决的经典题目
    poj 1026
    hdu 1394
    poj 3270
    poj 2154
    《重构 改善既有代码的设计》读书笔记2
    Android OpenGL ES: 渐变颜色的三角形
  • 原文地址:https://www.cnblogs.com/opbnbjs/p/9503797.html
Copyright © 2011-2022 走看看