UVALive 2678 子序列

来源:互联网 发布:itouch4怎么下载软件 编辑:程序博客网 时间:2024/06/05 03:32

题目链接: https://vjudge.net/problem/34000/origin

题意 : 有n(10<n<=100 000)个正整数a[i] (a[i]<10 000) 组成的一个序列.给定整数S,求长度最短的连续序列,使他们的和大于或等于S(S <1e9).

Sample Input

10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5

Sample output

2
3

分析:
只求和,可以先更新得到和序列,此时枚举左右端点(i,j)还是超时.注意到和序列是递增的,对于每个右端点我们要找到最大满足条件(s[j] - s[i] >= S)可以二分得到i,此时时间复杂度O(nlog(n))
可以进一步优化,若s[j]对应的i为x,那么s[j+1]对应的i一定大于等于x,也就说满足条件的i也是递增的,可以接着上次的i计算这次的i,也就最多只需找n次i;时间复杂度为O(n);



#include <iostream>#include <cstdio>using namespace std;int a[100100];int main(){    int n, s;    while(scanf("%d%d", &n, &s) != EOF)    {        a[0] = 0;        for(int i = 1; i <= n; i++)        {            scanf("%d", &a[i]);            a[i] += a[i - 1];        }        int i = 1;        int ans = n + 1;        for(int j = 1; j <= n; j++)        {            if(a[i - 1] > a[j] - s) continue;            while(a[i] <= a[j] - s) i++;            ans = min(ans, j - i + 1);        }        for(int i = 1; i <= n; i++)        {            for(int j = 1; j <= n; j++)            {                for(int k = j; )            }        }        printf("%d\n", ans == n + 1 ? 0 : ans);    }    return 0;}



0 0
原创粉丝点击