题面 题解(单调队列优化DP) 代码 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; const int N = 1e5 + 10; LL f[N]; LL s[N]; int q[N]; LL g(int i) { if (i == 0) return 0; return f[i - 1] - s[i]; } int main() { int n, k; scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) { scanf("%d", &s[i]); s[i] += s[i - 1]; //前缀和 } int hh = 0, tt = 0; for (int i = 1; i <= n; i++) { if (q[hh] < i - k) hh++; //超出滑动窗口,出队列 ,此时s[i]还没入队,因此取不到等于号 f[i] = max(f[i - 1], g(q[hh]) + s[i]); while (hh <= tt && g(q[tt]) <= g(i)) tt--; //维护一个单调递减队列,队头元素最大 q[++tt] = i; } printf("%lld\n", f[n]); return 0; }