第一行输入两个整数M和N,M,N<=200接下来M行,每行N个整数,表示矩阵中元素
输出一个整数,表示最大路径和
5 10 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
16
5 10 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 0 1
15
import java.util.*;
public class Main {
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int row = sc.nextInt();
int col = sc.nextInt();
int[][] matrix = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
matrix[i][j] = sc.nextInt();
}
}
System.out.println(cherryPick(matrix));
}
//解题思路:让两个小人从左上走到右下,两人都只能往右或往下走,因此其中一条就表示去时的路,
//而另一条表示回来时的路。因此当两人一旦相遇时,若该位置有樱桃,则记录为只拿了一次樱桃,否则
//则记录为拿了两次樱桃。运用递归找到最大拿取樱桃的数量
public static int cherryPick(int[][] m) {
if (m == null || m[0] == null)
return 0;
int N = m.length;
int M = m[0].length;
if (N == 0 || M == 0)
return 0;
int[][][] dp = new int[N][M][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
for (int k = 0; k < N; k++) {
dp[i][j][k] = -1;
}
}
}
return process(m, N, M, 0, 0, 0, dp);
}
//注意表示两小人坐标时,之所有没有y2是因为x1 + y1 == x2 + y2, 因此y2 = x1 + y1 - x2!
//此函是表示两小人从(x1, y1)与(x2, y2)位置出发,走到右下角的情况下,能获得的最大樱桃数是多少
//dp[x1][y1][x2] == -1: 要么还没算过当前结果,要么已经算过了是无效解,总之都不能直接用
public static int process(int[][] m, int N, int M, int x1, int y1, int x2, int[][][] dp) {
//越界了返回无效值
if (x1 == N || x2 == N || y1 == M || (x1 + y1 - x2) == M)
return -1;
if (dp[x1][y1][x2] != -1)
return dp[x1][y1][x2];
//当两人同时走到右下角
if (x1 == N-1 && x2 == x1) {
dp[x1][y1][x2] = m[N-1][M-1];
return m[N-1][M-1];
}
//找接下来能获得的最大樱桃数
int next = -1;
//1号小人往下走,2号小人往右走
next = Math.max(process(m, N, M, x1 + 1, y1, x2, dp), next);
//1号小人往下走,2号小人往下走
next = Math.max(process(m, N, M, x1 + 1, y1, x2 + 1, dp), next);
//1号小人往右走,2号小人往右走
next = Math.max(process(m, N, M, x1, y1 + 1, x2, dp), next);
//1号小人往右走,2号小人往右走
next = Math.max(process(m, N, M, x1, y1 + 1, x2 + 1, dp), next);
//如果下面干脆走不通,返回无效解
if (next == -1)
return -1;
//两人相遇时
if (x1 == x2) {
dp[x1][y1][x2] = m[x1][y1] + next;
}
else {
dp[x1][y1][x2] = m[x1][y1] + m[x2][x1+y1-x2] + next;
}
return dp[x1][y1][x2];
}
}