Go&Java算法之礼物的最大价值

402 阅读1分钟

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

礼物的最大价值

在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

 

示例 1:

输入: [   [1,3,1],   [1,5,1],   [4,2,1] ]

输出: 12

解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

提示:

0 < grid.length <= 200 0 < grid[0].length <= 200

题解

方法一:动态规划——Java

题目说明:从棋盘的左上角开始拿格子里的礼物,并每次 向右 或者 向下 移动一格、直到到达棋盘的右下角。 根据题目说明,易得某单元格只可能从上边单元格或左边单元格到达。

设 f(i, j) 为从棋盘左上角走至单元格 (i ,j)的礼物最大累计价值,易得到以下递推关系:f(i,j)) 等于 f(i,j-1) 和 f(i-1,j) 中的较大值加上当前单元格礼物价值 grid(i,j) 。

f(i,j)=max[f(i,j−1),f(i−1,j)]+grid(i,j)

因此,可用动态规划解决此问题,以上公式便为转移方程。

class Solution {
    public int maxValue(int[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
        for (int i = 1; i < grid[0].length; i++) {
            grid[0][i] += grid[0][i - 1];
        }
        for (int i = 1; i < grid.length; i++) {
            grid[i][0] += grid[i - 1][0];
        }
        for (int i = 1; i < grid.length; i++) {
            for (int j = 1; j < grid[0].length; j++) {
                grid[i][j] += Math.max(grid[i - 1][j], grid[i][j - 1]);
            }
        }
        return grid[grid.length - 1][grid[0].length - 1];
    }
}

时间复杂度:O(MN)

空间复杂度:O(N)

方法一:动态规划——Go

func maxValue(grid [][]int) int {
	dp := make([]int, len(grid[0]))
	for _, row := range grid {
		for j, cur := range row {
			if j == 0 {
				dp[j] += cur
			} else {
				dp[j] = max(dp[j-1], dp[j]) + cur
			}
		}
	}
	return dp[len(dp)-1]
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}