尺取法入门--poj 3061

来源:互联网 发布:大唐电信数据所 待遇 编辑:程序博客网 时间:2024/04/30 03:55

Subsequence
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 16457 Accepted: 6982

Description

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.

Input

The first line is the number of test cases. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.

Output

For each the case the program has to print the result on separate line of the output file.if no answer, print 0.

Sample Input

210 155 1 3 5 10 7 4 9 2 85 111 2 3 4 5

Sample Output

23

题的意思给出  a1,a2,a3,.....an-1  以及整数s,求总和不小于s的最短连续子序列,如果不存在输出0;


可以用区间【s,t)的总和 加二分快速搜索解决     sum[i]=a0+a1+a2+ai-1; 想要求得某一区间【s,t)的总和大于sum

可以枚举每一个数据,做一下操作:   元素(sum[i])

 求得当前元素sum【s】到sum【n】中的大于等于sum【s】+S的第一个元素的下标   t    然后用t减去s的下标  即为大于S的和的序列,  然后设一个更新最小值的语句,就可以求出最小值了

贴一下这个代码:

int n,s;int a[max]int sum[manx+1];void solve(){for(itn i=0;i<n;i++)sum[i+1]=sum[i]+a[i];if(sum[n]<S){cout<<0<<endl;return ;}int res=n;for(int s=0;sum[s]+S<=sum[n];s++){int t=lower_bound(sum+s,sum+n,sum[s]+S); //求得从s点到t点的大于等于S的t点坐标res=min(res,t-s);//求得了最小的区间}cout<<res<<endl;}  

这个算法的复杂度为  o(logn*n)  还可以优化,那当然是这篇文章的核心了,尺取法!!!

下面放思想:

以a[s]开始的总和大于S时的连续子序列为a[s], a[s+1],  a[s+2],;....a[t-1]>=S  ,1.是不是就有a[s]----a[t-2]<S了呢,2.是不是有 a[s+1]--a[t-1]<S了呢   开始说的标准区间就是从这两种情况演变过来的,因此 可以设计出一下算法

1)以s=t=sum=0开始

2)只要依然有sum<S;就不断增加a[t]并将t++;

3)如果2)中的无法满足sum>=S则终止,满足的直接更新res

4)将sum减去a[s],s++然后回到2)  (这个是基于3)成立的情况下才执行的操作)

在这个算法中,t最多变化n次,因此只需要o(n)的复杂度

下面放代码:

void solve(){itn res=n+1;int s=0,t=0,sum=0;for(;;){while(t<n&&sum<S)//加数加到大于等于S的操作sum+=a[t++];if(sum<S) break;//直接就确定了所有的元素之和都小于了Sres=min(res,t-s);sum-=a[s++];}if(res>n)res=0;cout<<res<<endl;}

这样反复推进区间的开头和末尾,来求取满足条件的最小区间的方法被称为尺取法。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 济宁住房公积金查询 住房公积金电话 沧州住房公积金 北京住房公积金管理中心 四川住房和城乡建设厅 佛山市住房公积金管理中心 住房公积金查询个人账户 19住房商业贷款利率 四川省住房和城乡建设厅首页 住房商业贷款利率 佛山住房公积金管理中心 四川住房城乡建设厅 西安住房公积金管理中心 住房公积金贷款额度 沧州住房公积金查询 个人住房公积金查询入口 银行住房贷款利率计算器 合肥市住房公积金管理中心 山东省住房和城乡建设厅 2019商业住房贷款利率 住房和城乡建设部 长春住房公积金 四川省住房城乡建设厅首页 新乡市住房公积金管理中心 住房贷款利率计算器 邵阳市住房公积金管理中心 邵阳住房公积金 商业住房贷款利率 陕西省住房公积金管理中心 合肥住房公积金管理中心 长春市住房公积金 山东省住房城乡建设厅 2019各银行住房商贷利率一览表 住房公积金查询入口 陕西省住房和城乡建设厅网 沧州住房公积金个人查询入口 包头市住房公积金管理中心 佛山住房公积金中心 个人住房商业性贷款 住房公积金装修贷款能贷多少 邵阳住房公积金管理中心