Subsequence UVALive - 2678 子序列

版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。 https://blog.csdn.net/qq_42835910/article/details/89817550

     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. 

分析:计算前缀和sum[i].那么问题就是对于j为终点,i为起点,枚举j,求解sum[j] - sum[i] >= s(即sum[i] <= sum[j] - s)成立时 i 的最大值(i越大,序列越短),ans = min{ j-i+1}。

方法一:二分,时间复杂度O(nlogn).

#include <cstdio>
#include <algorithm>
using namespace std; 
const int N = 100000 + 5;
int nums[N], sums[N];
int main(int argc, char** argv) {
	int n, s;
	while( ~scanf("%d%d",&n,&s)){		
		for(int i = 1; i <= n; i++){
			scanf("%d",&nums[i]);
			sums[i] = sums[i-1] + nums[i];
		}
		int ans = n+1;
		for(int j = n; j >= 1; j--){
			int y = sums[j] - s;
			if(y < 0) break; //前j个数的和小于s,后面不可能继续; 
			int i = lower_bound(sums ,sums+j, y) - sums;
			if(i > 0) ans = min(j-i+1,ans);
		}
		printf("%d\n",ans  == n+1 ? 0 : ans);
	}
	return 0;
}

方法二:由于j是递增的,那么sum[j] - s 的位置也是递增的,那么sum[i] <= sum[j] - s 的右边也是递增的,显然满足条件的

i也是递增的.时间复杂度O(n)

#include <cstdio>
#include <algorithm>
using namespace std; 
const int N = 100000 + 5;
int nums[N], sums[N];
int main(int argc, char** argv) {
	int n, s;
	while( ~scanf("%d%d",&n,&s)){		
		for(int i = 1; i <= n; i++){
			scanf("%d",&nums[i]);
			sums[i] = sums[i-1] + nums[i];
		}
		int ans = n+1, i = 1; 
		for(int j = 1; j <= n; j++){
			int y = sums[j] - s;
			if(y < 0) continue; 	//没有满足条件的i,换下一个j 
			while(sums[i] <= y) i++; //求满足b[i-1] <= b[j] - s 的最大i 
			ans = min(j-i+1,ans);
		}
		printf("%d\n",ans  == n+1 ? 0 : ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42835910/article/details/89817550