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