[POJ] 3061 Subsequence (尺取法)

题目地址:http://poj.org/problem?id=3061

方法一:因为元素都大于0,所以维护前缀和sum[i],一定有sum[k]>sum[i](k>i)。这样子序列起点s确定以后,用二分查找确定使序列和不小于s的结尾t的最小值。

    时间复杂度o(nlogn)。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<string.h>
 4 #include<algorithm>
 5 #include<math.h>
 6 #include<stdbool.h>
 7 #include<time.h>
 8 #include<stdlib.h>
 9 #include<map>
10 #include<stack>
11 #include<queue>
12 #include<vector>
13 using namespace std;
14 #define clr(x,y)    memset(x,y,sizeof(x))
15 #define sqr(x)      ((x)*(x))
16 #define rep(i,a,b)  for(int i=(a);i<=(b);i++)
17 #define LL          long long
18 #define INF         0x3f3f3f3f
19 #define A           first
20 #define B           second
21 const int N=1e5+131;
22 int    n,s,a[N],sum[N];
23 
24 void init()
25 {
26     clr(a,0);
27     clr(sum,0);
28 }
29 void solve()
30 {
31     int cas;
32     
33     scanf("%d",&cas);
34     while(cas--){
35         init();
36         scanf("%d%d",&n,&s);
37         for(int i=0;i<n;i++) {
38             scanf("%d",&a[i]);
39             sum[i+1]=sum[i]+a[i];
40         }
41         int res=n+1;
42         for(int k=0;sum[k]+s<=sum[n];k++){
43             int p=lower_bound(sum+k,sum+n,sum[k]+s)-sum;
44             res=min(res,p-k);
45         }
46         if(res>n){
47             puts("0");
48             continue;
49         }
50         printf("%d\n",res);
51     }
52     
53 }
54 
55 int main()
56 {
57     solve();
58     return 0;
59 }

方法二:尺取法。时间复杂度o(n)。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<string.h>
 4 #include<algorithm>
 5 #include<math.h>
 6 #include<stdbool.h>
 7 #include<time.h>
 8 #include<stdlib.h>
 9 #include<map>
10 #include<stack>
11 #include<queue>
12 #include<vector>
13 using namespace std;
14 #define clr(x,y)    memset(x,y,sizeof(x))
15 #define sqr(x)      ((x)*(x))
16 #define rep(i,a,b)  for(int i=(a);i<=(b);i++)
17 #define LL          long long
18 #define INF         0x3f3f3f3f
19 #define A           first
20 #define B           second
21 const int N=1e5+131;
22 int    n,s,a[N];
23 
24 
25 void solve()
26 {
27     int cas;
28     
29     scanf("%d",&cas);
30     while(cas--) {
31         scanf("%d%d",&n,&s);
32         for(int i=0;i<n;i++) {
33             scanf("%d",&a[i]);        
34         }
35         
36         int t=0,sum=0,h=0,res=n+1;
37         
38         while(true) {
39              while(t<n && sum<s) {
40                 sum+=a[t++];
41              }
42             if(sum<s) break;
43             res=min(res,t-h); 
44             sum-=a[h++];
45         }
46         if(res>n) {
47             puts("0");
48             continue;
49         }
50         printf("%d\n",res);
51     }
52 }
53 
54 int main()
55 {
56     solve();
57     
58     return 0;
59 }

 

posted @ 2015-03-21 10:14  SXISZERO  阅读(162)  评论(0编辑  收藏  举报