社区讨论

用单调队列但并没有时间上的优化??

P2254[NOI2005] 瑰丽华尔兹参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@m2gwhnwa
此快照首次捕获于
2024/10/20 09:20
去年
此快照最后确认于
2024/10/20 11:18
去年
查看原帖
C
#include <bits/stdc++.h>
using namespace std;
const int N = 205;
int n, m, x, y, p, t[N], d[N];
char a[N][N];
int ans = 0, f[N][N][N];
int l1, r1, l2, r2, l3, r3, l4, r4, q1[N], q2[N], q3[N], q4[N];

int calc1(int u, int j, int k) {
	return f[u][j][k - 1] + u;
}

int calc2(int u, int j, int k) {
	return f[u][j][k - 1] - u;
}

int calc3(int i, int u, int k) {
	return f[i][u][k - 1] + u;
}

int calc4(int i, int u, int k) {
	return f[i][u][k - 1] - u;
}

int main() {
	scanf("%d%d%d%d%d", &n, &m, &x, &y, &p);
	for (int i = 1; i <= n; i ++)
		for (int j = 1; j <= m; j ++)
			cin >> a[i][j];
	
	for (int i = 1; i <= p; i ++) {
		int u, w;
		scanf("%d%d%d", &u, &w, &d[i]);
		t[i] = w - u + 1;
	}
	
	memset(f, -0x3f, sizeof f);
	f[x][y][0] = 0;
	
		for (int k = 1; k <= p; k ++)
			if (d[k] == 1) {
				for (int j = 1; j <= m; j ++) {
					q1[l1 = r1 = 1] = 0;
					for (int i = n; i >= 1; i --) {
						if (a[i][j] != '.') q1[l1 = r1 = 1] = 0;
						else {
							f[i][j][k] = f[i][j][k - 1];
							while (l1 <= r1 && calc1(q1[r1], j, k) <= calc1(i, j, k)) r1 --;
							q1[++ r1] = i;
							while (l1 <= r1 && q1[l1] > i + t[k]) l1 ++;
							if (l1 <= r1) f[i][j][k] = max(calc1(q1[l1], j, k) - i, f[i][j][k]);
						}
					}
				}
			}
			else if (d[k] == 2) {
				for (int j = 1; j <= m; j ++) {
					q2[l2 = r2 = 1] = 0;
					for (int i = 1; i <= n; i ++) {
						if (a[i][j] != '.') q2[l2 = r2 = 1] = 0;
						else {
							f[i][j][k] = f[i][j][k - 1];
							while (l2 <= r2 && calc2(q2[r2], j, k) <= calc2(i, j, k)) r2 --;
							q2[++ r2] = i;
							while (l2 <= r2 && q2[l2] < i - t[k]) l2 ++;
							if (l2 <= r2) f[i][j][k] = max(calc2(q2[l2], j, k) + i, f[i][j][k]);
						}
					}
				}
			}
			else if (d[k] == 3) {
				for (int i = 1; i <= n; i ++) {
					q3[l3 = r3 = 1] = 0;
					for (int j = m; j >= 1; j --) {
						if (a[i][j] != '.') q3[l3 = r3 = 1] = 0;
						else {
							f[i][j][k] = f[i][j][k - 1];
							while (l3 <= r3 && calc3(i, q3[r3], k) <= calc3(i, j, k)) r3 --;
							q3[++ r3] = j;
							while (l3 <= r3 && q3[l3] > j + t[k]) l3 ++;
							if (l3 <= r3) f[i][j][k] = max(calc3(i, q3[l3], k) - j, f[i][j][k]);
						}
					}
				}
			}
			else {
				for (int i = 1; i <= n; i ++) {
					q4[l4 = r4 = 1] = 0;
					for (int j = 1; j <= m; j ++) {
						if (a[i][j] != '.') q4[l4 = r4 = 1] = 0;
						else {
							f[i][j][k] = f[i][j][k - 1];
							while (l4 <= r4 && calc4(i, q4[r4], k) <= calc4(i, j, k)) r4 --;
							q4[++ r4] = j;
							while (l4 <= r4 && q4[l4] < j - t[k]) l4 ++;
							if (l4 <= r4) f[i][j][k] = max(calc4(i, q4[l4], k) + j, f[i][j][k]);
						}
					}
				}
			}
	
	for (int i = 1; i <= n; i ++)
		for (int j = 1; j <= m; j ++)
			ans = max(ans, f[i][j][p]);
	
	printf("%d\n", ans);
	
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...