[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 }

 

你可能感兴趣的:(sequence)