#include <iostream>
#include <algorithm>
using namespace std;
const int N = 15;
int n;
int w[N][N];
int f[N * 2][N][N];
int main()
{
scanf("%d", &n);
int a, b, c;
while(cin >> a >> b >> c, a || b || c)
{
w[a][b] = c;
}
for(int k = 2; k <= n + n; k++)
{
for(int i1 = 1; i1 <= n; i1++)
{
for(int i2 = 1; i2 <= n; i2++)
{
int j1 = k - i1, j2 = k - i2;
if(j1 >= 1 && j1 <= n && j2 >= 1 && j2 <= n)
{
int t = w[i1][j1];
if(i1 != i2)
{
t += w[i2][j2];
}
int &x = f[k][i1][i2];
x = max(x, f[k - 1][i1 - 1][i2 - 1] + t);
x = max(x, f[k - 1][i1 - 1][i2] + t);
x = max(x, f[k - 1][i1][i2 - 1] + t);
x = max(x, f[k - 1][i1][i2] + t);
}
}
}
}
printf("%d\n", f[n + n][n][n]);
return 0;
}
/*
走两次可以先走、后走和同时走,这里举例同时走:
f(i1, j1, i2, j2)表示所有从(1, 1), (1, 1)分别走到
(i1, j1), (i2, j2)的路径的最大值,如何处理“同一个
格子不能被重复选择”
只有在i1 + j1 == i2 + j2时, 两条路径的格子才可能
重合。
f(k, i1, i2)表示所有从(1, 1), (1, 1)分别走到
(i1, j1), (i2, j2)的路径的最大值,k表示两条路线
当前走到格子的横纵坐标之和;
k = i1 + j1 = i2 + j2;
则f(k, i1, i2)就有了 4 种状态转移
1、第一条:下;第二条:下
2、第一条:下;第二条:右
3、第一条:右;第二条:下
4、第一条:右;第二条:右
以第一个举例:
(1, 1) -> ... -> (i1 - 1, j1) -> (i1, j1)
(1, 1) -> ... -> (i2 - 1, j2) -> (i2, j2)
则有两种情况,一种是(i1, j1)和(i2, j2)重合,
另一种是(i1, j1)和(i2, j2)不重合
所以f(k, i1, i2) = max(f(k, i1, i2),f(k - 1, i1 - 1, i2 - 1)
+(w(i1, j1) + w(i2, j2) or (w(i1, j1)两种情况;
*/
算法提高课——AcWing 1027. 方格取数
最新推荐文章于 2024-09-09 19:45:49 发布