网上的解法解释很多,但是java版本的代码似乎比较难找,再次贡献自己的代码。Vijos和BJTUOJ已过。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int[][] map = new int[22][22];
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
map[i][j] = in.nextInt();
}
}
int[][][][] dp = new int[41][21][21][21];
dp[1][1][1][1] = map[1][1] * 3;
for (int l = 1; l <= 2 * N - 1; l++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
for (int k = 1; k <= N; k++) {
int i1 = l - i + 1;
int j1 = l - j + 1;
int k1 = l - k + 1;
//不合适的坐标点剔除
if(i1 < 0 || j1 < 0 || k1 < 0 || i1 >= 21 || j1 >= 21 || k1 >= 21){
continue;
}
List<Integer> paths = new ArrayList<>();
paths.add(dp[l - 1][i - 1][j - 1][k - 1]);
paths.add(dp[l - 1][i - 1][j - 1][k]);
paths.add(dp[l - 1][i - 1][j][k - 1]);
paths.add(dp[l - 1][i - 1][j][k]);
paths.add(dp[l - 1][i][j - 1][k - 1]);
paths.add(dp[l - 1][i][j - 1][k]);
paths.add(dp[l - 1][i][j][k - 1]);
paths.add(dp[l - 1][i][j][k]);
dp[l][i][j][k] = Collections.max(paths) + map[i][i1] + map[j][j1] + map[k][k1];
//若有人在同一点,减去当前map坐标值,表示为走过的点为0
if(i == j) dp[l][i][j][k] -= map[i][i1];
if(i == k) dp[l][i][j][k] -= map[i][i1];
if(j == k) dp[l][i][j][k] -= map[j][j1];
if(i == j && j == k) dp[l][i][j][k] += map[i][i1];
}
}
}
}
int ans = dp[2 * N - 1][N][N][N];
System.out.print(ans);
}
}