为什么不能用两个单调队列?
  • 板块P3800 Power收集
  • 楼主C_Z_C
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/2/27 10:40
  • 上次更新2023/10/28 07:38:09
查看原帖
为什么不能用两个单调队列?
123078
C_Z_C楼主2022/2/27 10:40

下面是我用两个单调队列做的,一个维护[j - t, j]的最大值,另一个维护[j + 1, j + t]的最大值,然后转移的时候再取两个队列队头元素的最大值。但是为什么只有10pt呢?

#include <iostream>
#include <cstdio>

using namespace std;

int read(){
	int s = 0;
	char c = getchar();
	while(c > '9' || c < '0') c = getchar();
	while(c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
	return s;
}

const int N = 4e3 + 5;

int n = read(), m = read(), k = read(), T = read(), a[N][N], dp[N][N];
int front1[N], rear1[N], front2[N], rear2[N], q1[N], q2[N], maxn;

int main(){
	for(int i = 1; i <= k; i++){
		int x = read(), y = read(), v = read();
		a[x][y] = v;
	}
	for(int i = 1; i <= m; i++) dp[1][i] = a[1][i];
	for(int i = 2; i <= n; i++){
		front1[i] = front2[i] = 1;
		for(int j = 1; j <= 1 + T; j++){
			while(front2[i] <= rear2[i] && dp[i - 1][j] >= dp[i - 1][rear2[i]]) rear2[i]--;
			q2[++rear2[i]] = j;
		}
		for(int j = 1; j <= m; j++){
			while(front1[i] <= rear1[i] && q1[front1[i]] < j - T) front1[i]++;
			while(front2[i] <= rear2[i] && q2[front2[i]] < j) front2[i]++;
			dp[i][j] = max(dp[i - 1][q1[front1[i]]], dp[i - 1][q2[front2[i]]]) + a[i][j];
			while(front1[i] <= rear1[i] && dp[i - 1][j] >= dp[i - 1][q1[rear1[i]]]) rear1[i]--;
			q1[++rear1[i]] = j;
			while(front2[i] <= rear2[i] && dp[i - 1][j + T + 1] >= dp[i - 1][q2[rear2[i]]]) rear2[i]--;
			q2[++rear2[i]] = j + T + 1;
		}
	}
	for(int i = 1; i <= m; i++) maxn = max(maxn, dp[n][i]);
	cout << maxn;
	return 0;
}

一个单调队列:

#include <iostream>
#include <cstdio>

using namespace std;

int read(){
	int s = 0;
	char c = getchar();
	while(c > '9' || c < '0') c = getchar();
	while(c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
	return s;
}

const int N = 4e3 + 5;

int n = read(), m = read(), k = read(), T = read(), a[N][N], dp[N][N];
int front, rear, q[N], maxn;

int main(){
	for(int i = 1; i <= k; i++){
		int x = read(), y = read(), v = read();
		a[x][y] = v;
	}
	for(int i = 1; i <= m; i++) dp[1][i] = a[1][i];
	for(int i = 2; i <= n; i++){
		front = 1, rear = 0;
		for(int j = 1; j <= T; j++){
			while(front <= rear && dp[i - 1][j] >= dp[i - 1][q[rear]]) rear--;
			q[++rear] = j;
		}
		for(int j = 1; j <= m; j++){
			while(front <= rear && q[front] < j - T) front++;
			if(j + T <= m){
				while(front <= rear && dp[i - 1][j + T] >= dp[i - 1][q[rear]]) rear--;
				q[++rear] = j + T;
			}
			dp[i][j] = dp[i - 1][q[front]] + a[i][j];
		}
	}
	for(int i = 1; i <= m; i++) maxn = max(maxn, dp[n][i]);
	cout << maxn;
	return 0;
}```
2022/2/27 10:40
加载中...