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;
}