卷王 @ 2023-07-21 20:38:48
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read() {
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); }
return x * f;
}
int n, k, head = 0, tail = 1;
int a[100007], q[100007];
ll sum[100007], tmp[100007], dp[100007]; //dp[i] 表示到了第 i 只奶牛时的最大效率值
int main() {
n = read(), k = read();
for(int i = 1; i <= n; i++)
a[i] = read(), sum[i] = sum[i - 1] + a[i];
for(int i = 1; i <= n; i++) {
tmp[i] = dp[i - 1] - sum[i];
while(head <= tail && tmp[q[tail]] < tmp[i]) tail--;
q[++tail] = i;
while(head <= tail && q[head] + k < i) head++;
dp[i] = tmp[q[head]] + sum[i];
}
cout << dp[n];
return 0;
}
根据第二篇题解代码写的,但是有一个问题,就是为什么
理由一:第二篇题解里的评论区 @海曜日 大佬说了:
才发现写成了 head = 0, tail = 1,我猜这是误打误撞的结果
理由二:我请教了好多大佬(甚至有金钩的),但是他们都说可能是数据水,题解代码是误打误撞的。
理由三:我也查过许多资料,上面说:
单调队列的基本写法就是 head = 1, tail = 0。
当然,之前问过一个助教,他说有时为了方便,也可以写成
欢迎各位发表一下自己的看法,反正我觉的可以 @管理员 撤掉第二篇题解了。
by 卷王 @ 2023-07-21 20:39:51
@管理员 @海曜日
by 卷王 @ 2023-07-21 20:43:07
还有,评论区翻到最底下(第二篇题解)就可以看到 @Frozen_Heart 大佬的评论,他也这么认为。我感觉这个问题可以好好探讨一下了。。。
by _•́へ•́╬_ @ 2023-07-21 20:46:17
多放进去的都是0啊
by Accelessar @ 2023-07-21 20:48:12
我觉得这个应该没啥问题吧?我一般都用的 head=1,tail=1
也没出过问题啊?
我觉得可能是在两个 while 那边都统一掉了。
by Accelessar @ 2023-07-21 20:50:28
楼上的楼上说的对,多放几个 0 对答案应该也没影响
by 卷王 @ 2023-08-01 19:59:01
啊??!
by 卷王 @ 2023-08-01 19:59:12
哦谢谢
by Iniaugoty @ 2023-08-04 13:23:28
@Wicked_Game 大神犇你好,这个要看是左闭右闭还是左闭右开吧,而且和实现也有关系,有的时候队列开头就要方个0