思路四:优化dp数组的动态规划,画图解决
代码
//1.暴力递归 public int maxValue(int[][] grid) { return recur(grid, grid.length - 1, grid[0].length - 1); } public int recur(int[][] grid ,int i, int j) { if (i == 0 && j == 0) return grid[0][0]; if (i < 0 || j < 0) return -1; int value1 = recur(grid, i, j - 1); int value2 = recur(grid, i - 1, j); return value1 == -1 && value2 == -1 ? -1 : Math.max(value1, value2) + grid[i][j]; } //2. 备忘录 int[][] dp; public int maxValue(int[][] grid) { dp = new int[grid.length][grid[0].length]; return recur(grid, grid.length - 1, grid[0].length - 1); } public int recur(int[][] grid ,int i, int j) { if (i == 0 && j == 0) return grid[0][0]; if (i < 0 || j < 0) return -1; if (dp[i][j] != 0) return dp[i][j]; int value1 = recur(grid, i, j - 1); int value2 = recur(grid, i - 1, j); dp[i][j] = value1 == -1 && value2 == -1 ? -1 : Math.max(value1, value2) + grid[i][j]; return dp[i][j]; } //3.动态规划 public int maxValue(int[][] grid) { //表示从(0,0)到(i,j)获得礼物的最大 int[][] dp = new int[grid.length][grid[0].length]; dp[0][0] = grid[0][0]; for (int i = 1; i < grid.length; i++) { dp[i][0] += dp[i - 1][0] + grid[i][0]; } for (int j = 1; j < grid[0].length; j++) { dp[0][j] += dp[0][j - 1] + grid[0][j]; } for (int i = 1; i < grid.length; i++) { for (int j = 1; j < grid[0].length; j++) { dp[i][j] += Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; } } return dp[grid.length - 1][grid[0].length - 1]; } //4.优化dp数组动态规划,由于每次只用到前一行和前一个,所以可以优化为一维dp数组 public int maxValue(int[][] grid) { //表示从(0,0)到(i,j)获得礼物的最大 int[] dp = new int[grid[0].length]; dp[0] = grid[0][0]; for (int j = 1; j < grid[0].length; j++) { dp[j] += dp[j - 1] + grid[0][j]; } for (int i = 1; i < grid.length; i++) { dp[0] += grid[i][0]; for (int j = 1; j < grid[0].length; j++) { dp[j] = Math.max(dp[j], dp[j - 1]) + grid[i][j]; } } return dp[grid[0].length - 1]; }
礼物的最大价值