uva2678

题意是求最短子序列使得和>=给定的S,ai>=0。

前缀和是必然的,因为涉及到子序列和。

尝试枚举终点,对于终点j,只需要找到满足Bj - Bi-1 >= S的最大的i。(因为长度要尽量短)

由于Bn是递增的,那么随着j的增大,相应的i也要增大。

故用一个单调栈实现即可。

实现见代码

#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 10;

int n, S;

int a[maxn], b[maxn];

void solve()
{
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++)
        b[i] = b[i - 1] + a[i];
    int ans = n + 1;
    int i = 1;
    for (int j = 1; j <= n; j++)
    {
        if (b[i - 1] > b[j] - S) continue;
        while (b[i] <= b[j] - S) i++;
        ans = min(ans, j - i + 1);
    }
    printf("%d\n", ans == n + 1? 0 : ans);
}

int main()
{
    while(~scanf("%d%d", &n, &S)) solve();
    return 0;
}

 

posted @ 2017-10-20 22:07  yohanlong  阅读(128)  评论(0编辑  收藏  举报