加点时,我把大于改成大于等于就过了
原来是这样写的
while(head <= tail && f[i - 1][j] > f[i - 1][Q[tail]]) tail--;
改成这样写
while(head <= tail && f[i - 1][j] >= f[i - 1][Q[tail]]) tail--;
就过了。答案偏大。
#include<bits/stdc++.h>
#define int long long
#define N 4010
using namespace std;
int n, m, k, T, ans;
int val[N][N], f[N][N];
int max(int a, int b) {
return a > b ? a : b;
}
int min(int a, int b) {
return a < b ? a : b;
}
int Q[N], head, tail = 0;
signed main() {
cin >> n >> m >> k >> T;
for(int i = 1; i <= k; i++) {
int x, y, v;
cin >> x >> y >> v;
val[x][y] = v;
f[x][y] = v;
}
for(int i = 1; i <= n; i++) {
head = 1, tail = 0;
for(int j = 1; j <= m + T; j++) {
while(head <= tail && Q[head] < j - 2 * T) head++;
if(j <= m) while(head <= tail && f[i - 1][j] >= f[i - 1][Q[tail]]) tail--;
Q[++tail] = j;
if(j > T && head <= tail) f[i][j - T] = max(f[i][j - T], f[i - 1][Q[head]] + val[i][j - T]);
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) ans = max(ans, f[i][j]);
cout << ans;
return 0;
}