为什么这个题要维护严格单调
查看原帖
为什么这个题要维护严格单调
490978
小超手123楼主2023/11/7 20:08

加点时,我把大于改成大于等于就过了

原来是这样写的

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;
}
2023/11/7 20:08
加载中...