Subsequence(POJ 3061)
阿新 • • 發佈:2018-08-21
序列 second greate amp read rst 利用 etc separate
- 原題如下:
Subsequence
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 21032 Accepted: 8975 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
Output
Sample Input
2 10 15 5 1 3 5 10 7 4 9 2 8 5 11 1 2 3 4 5
Sample Output
2 3
- 題解:由於所有的元素大於0,假設存在子序列[s,t)滿足as+…+at-1≥S,那麽對於任何的t‘>t一定有as+…+at‘-1≥S。另外,如果令sum(i)=a0+a1+…+ai-1,那麽as+as+1…+at-1=sum(t)-sum(s),所以預先計算好sum的話,可以用O(1)的時間計算區間上的總和,這樣一來,子序列的起點s確定以後,便可以用二分搜索快速確定使序列和不小於S的結尾t的最小值,這個算法的復雜度是O(nlogn)。還有一種更為高效的算法,設以as
①以s=t=sum=0初始化
②只要依然有sum<S,就不斷將sum增加at,並將t增加1
③如果②中無法滿足sum≥S則終止,否則,更新res=min(res, t-s)
④將sum減去as,s增加1然後回到②
對於這個算法,因為s,t只能不斷地增大,最多變化n次,因此只需O(n)的復雜度就可以求解這個問題了,像這樣反復地推進區間的開頭和結尾,來求取滿足條件的最小區間的方法被稱為尺取法。 - 代碼1:
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #include <cmath> 5 #define num s-‘0‘ 6 7 using namespace std; 8 9 const int MAX_N=1000000; 10 const int INF=0x3f3f3f3f; 11 int n,S,t; 12 int a[MAX_N],sum[MAX_N+1]; 13 14 int min(int x, int y) 15 { 16 if (x<y) return x; 17 return y; 18 } 19 20 void read(int &x){ 21 char s; 22 x=0; 23 bool flag=0; 24 while(!isdigit(s=getchar())) 25 (s==‘-‘)&&(flag=true); 26 for(x=num;isdigit(s=getchar());x=x*10+num); 27 (flag)&&(x=-x); 28 } 29 30 void write(int x) 31 { 32 if(x<0) 33 { 34 putchar(‘-‘); 35 x=-x; 36 } 37 if(x>9) 38 write(x/10); 39 putchar(x%10+‘0‘); 40 } 41 42 int main() 43 { 44 read(t); 45 while (t>0) 46 { 47 read(n);read(S); 48 for (int i=0; i<n; i++) 49 { 50 read(a[i]); 51 sum[i+1]=sum[i]+a[i]; 52 } 53 int res=n+1; 54 for (int s=0; sum[n]-sum[s]>=S; s++) 55 { 56 int t=lower_bound(sum+s,sum+n,sum[s]+S)-sum; 57 res=min(res,t-s); 58 } 59 if (res<=n) write(res); 60 else write(0); 61 putchar(‘\n‘); 62 --t; 63 } 64 }
代碼2:
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #include <cmath> 5 #define num s-‘0‘ 6 7 using namespace std; 8 9 const int MAX_N=1000000; 10 const int INF=0x3f3f3f3f; 11 int n,S,m; 12 int a[MAX_N]; 13 14 int min(int x, int y) 15 { 16 if (x<y) return x; 17 return y; 18 } 19 20 void read(int &x){ 21 char s; 22 x=0; 23 bool flag=0; 24 while(!isdigit(s=getchar())) 25 (s==‘-‘)&&(flag=true); 26 for(x=num;isdigit(s=getchar());x=x*10+num); 27 (flag)&&(x=-x); 28 } 29 30 void write(int x) 31 { 32 if(x<0) 33 { 34 putchar(‘-‘); 35 x=-x; 36 } 37 if(x>9) 38 write(x/10); 39 putchar(x%10+‘0‘); 40 } 41 42 int main() 43 { 44 read(m); 45 while (m>0) 46 { 47 read(n);read(S); 48 for (int i=0; i<n; i++) 49 { 50 read(a[i]); 51 } 52 int s,t,sum; 53 s=t=sum=0; 54 int res=n+1; 55 for (;;) 56 { 57 while (t<n && sum<S) sum+=a[t++]; 58 if (sum<S) break; 59 res = min(res,t-s); 60 sum-=a[s++]; 61 } 62 if (res>n) res=0; 63 write(res); 64 putchar(‘\n‘); 65 --m; 66 } 67 }
Subsequence(POJ 3061)