题意是求最短子序列使得和>=给定的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 ", ans == n + 1? 0 : ans); } int main() { while(~scanf("%d%d", &n, &S)) solve(); return 0; }