利用前缀缩减计算量,结合二分查找可以把计算量缩减到O(n*long(n)),继续做优化,核心的思想是找最大的j,使得sum[j] <= sum[i] - S成立,i从1到n迭代的过程中,不等式右边是递增的,而sum数组也是递增的,所以j在迭代过程中也是递增的,所以可以动态确定每次迭代过程中j的下限是上一次迭代中得到的j,计算的时间复杂度就缩减到O(n)了
#include <stdio.h>
#define INF 0x7fffffff
int arr[100001];
int sum[100001];
void func(int n, int s){
int i, j, start, min, len;
sum[0] = 0;
start = 0;
min = INF;
for(i=1; i<=n; i++){
sum[i] = sum[i-1]+arr[i];
j = start;
for(j=i-1; j>=start; j--){
if(sum[j] <= sum[i]-s)
break;
}
if(j == start-1)
continue;
start = j;
len = i-j;
if(len < min)
min = len;
}
if(min == INF){
printf("0\n");
}
else{
printf("%d\n", min);
}
}
int main(void){
int num_n, s;
int n, i;
//freopen("input.dat", "r", stdin);
while(scanf("%d %d", &num_n, &s) != EOF){
for(i=1; i<=num_n; i++){
scanf("%d", arr+i);
}
func(num_n, s);
}
return 0;
}