poj3061 Subsequence 尺取法

来源:互联网 发布:送给红颜知已的歌曲 编辑:程序博客网 时间:2024/04/29 05:40

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is greater than or equal to S.

题意:一串长度为n的整数数列,从a1~an。再给出一个数s,求出总和大于等于s的连续子序列的长度的最小值。如果不存在则输出0.

题解:用到一个非常巧妙的处理方法:尺取法。我们可以计算出sum(i)=a0+a1+...+ai。那么sum(t)-sum(s)=as+a(s+1)+...a(t-1)。这样我们可以实现先求出一个sum(n)。sum(n)-sum(i)=s。我们只需要去筛选sum(i)。这样可以用二分搜索的方法快速求出最小的长度。

int t=lower_bound(sum+i,sum+n,sum[i]+s)-sum;求出来的是从sum[i]到sum[n]的,比sum[i]-s小的最小值的下标。

#include<iostream>#include<cstring>#include<algorithm>using namespace std;int n,s;int a[100005];int sum[100005];int main(){    int T;    cin>>T;    while(T--)    {        cin>>n>>s;        memset(sum,0,sizeof(sum));        for(int i=0;i<n;i++)        {            cin>>a[i];            sum[i+1]=sum[i]+a[i];        }       // cout<<sum[n]<<endl;        if(sum[n]<s)        {            cout<<"0"<<endl;        }        else        {            int ret=n;            for(int i=0;sum[i]+s<=sum[n];i++)            {                int t=lower_bound(sum+i,sum+n,sum[i]+s)-sum;                ret=min(ret,t-i);            }            cout<<ret<<endl;        }    }    return 0;}


原创粉丝点击