CF1941E 题解
纪念一下蒟蒻第一次不看题解独立 AC 单调队列优化 dp。
思路
这题其实和 P1725 琪露诺很类似,这题的 可以从 转移过来,然后当然选最小的,所以 ,然后这个最小值可以用单调队列维护。为了省时,我用了不带 的手写单调队列。
最后因为要求连续的 行,所以可以用前缀和维护。
代码
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
const ll inf = 1e18;
int t, n, m, x, k, d;
ll dp[200005], s[200005], minx;
deque <int> q;
int main () {
ios::sync_with_stdio (0);
cin.tie (0);
cout.tie (0);
cin >> t;
while (t --) {
cin >> n >> m >> k >> d;
++ d;
for (int i = 1; i <= n; ++ i) {
q.clear ();
for (int j = 1; j <= m; ++ j) {
cin >> x;
++ x;
while (! q.empty () && q.front () < j - d)
q.pop_front (); //过期了,删掉
dp[j] = q.empty () ? x : dp[q.front ()] + x;
while (! q.empty () && dp[q.back ()] >= dp[j])
q.pop_back (); //把 >= dp[j] 的全部单调队列了(删了)
q.push_back (j); //在队尾插入
}
s[i] = s[i - 1] + dp[m]; //前缀和
}
minx = inf;
for (int i = k; i <= n; ++ i)
minx = min (minx, s[i] - s[i - k]);
cout << minx << '\n';
}
return 0;
}

浙公网安备 33010602011771号