返回顶部
扩大
缩小

2020.3.16 Luogu1004方格取数

显然DP
与传纸条类似,拆成两个人
方法尽量变简单,即把A出发,B出发合并成两个A出发,两个A同时走,这样可以避免A取完B再取的无法判断的情况
状态转移方程:
1.\(x == z \; and \;y == d\),\(f[x][y][z][t] = max(f[x - 1][y][z - 1][t], f[x - 1][y][z][t - 1], f[x][y - 1][z - 1][t], f[x][y - 1][z][t - 1]) + a[x][y]\)
2.else,\(f[x][y][z][t] = max(f[x - 1][y][z - 1][t], f[x - 1][y][z][t - 1], f[x][y - 1][z - 1][t], f[x][y - 1][z][t - 1]) + a[x][y] + a[z][t]\)

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 10;

int n, a[N][N], x, y, z;
int f[N][N][N][N];

inline int DP(int x, int y, int z, int t)
{
	if (x == 0 || y == 0 || z == 0 || t == 0)
		return 0;
	if (f[x][y][z][t] != -1)
		return f[x][y][z][t];
	int ret = max(DP(x - 1, y, z - 1, t), max(DP(x - 1, y, z, t - 1), max(DP(x, y - 1, z - 1, t), DP(x, y - 1, z, t - 1))));
	if (x == z && y == t)
		ret += a[x][y];
	else
		ret += a[x][y] + a[z][t];
	return f[x][y][z][t] = ret;
}

int main()
{
	cin >> n;
	while (cin >> x >> y >> z)
	{
		if (x == 0 && y == 0 && z == 0)
			break ;
		a[x][y] = z;
	}
	memset(f, -1, sizeof f);
	f[1][1][1][1] = a[1][1];
	cout << DP(n, n, n, n) << endl;
	return 0;
}
posted @ 2020-03-16 21:17  Asasino  阅读(154)  评论(0编辑  收藏  举报