剑指笔记——47 礼物的最大值

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

思路:剑指中的思路如下:这道题可以使用动态规划解决问题。可以先用递归的思路分析。可以定义一个函数f(i,j)表示达到坐标(i,j)的格子时能拿到的礼物总和的最大值。由题目可知,有两种方法可以到达这个位置,即通过格子(i-1,j),(i,j-1)。所以有以下公式成立:

f(i,j)=max(f(i-1,j),f(i,j-1))+gift[i,j]

但是使用递归的话会有大量重复的计算,因此使用循环。为了保存中间计算的结果,我们使用一个辅助的二维数组,各个位置表示能拿到的礼物价值总和的最大值。这种思路是代码1.

可以对代码1进行优化。(i,j)的值d和只与(i-1,j),(i,j-1)有关,因此第i-2行以及更上面的最大值并不需要保存下来。因此可以使用一个一维数组来保存。一维数组的长度是棋盘的列数,数组中前i个数字保存的是f(i,0),f(i,1),f(i,2)....f(i,j-1),数组后面的数字是f(i-1,j),f(i-1,j+1),...f(i-1,n-1).我们只需要第i个和i-1个数组元素。这种思路是代码2.

代码来源:https://blog.csdn.net/weixin_37672169/article/details/80965894

代码1:

public class GreatestGift {

    public int getMaxValue(int[][] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }

        int rows = arr.length;
        int cols = arr[0].length;

        int[][] maxValue = new int[rows][cols];

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {  //遍历棋盘上的每一个元素
                int left = 0;
                int up = 0;
                if(i>0){
                    up = maxValue[i-1][j];  //当前元素上面的元素
                }
                if(j>0){
                    left = maxValue[i][j-1];  //当前元素左边的元素
                }
                maxValue[i][j] = Math.max(up, left) + arr[i][j];
            }
        }
        return maxValue[rows-1][cols-1];
    }
}

代码2:

/**
 * 礼物的最大价值(使用循环实现)
 */
public class GreatestGift2 {

    public int getMaxValue(int[][] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }

        int rows = arr.length;
        int cols = arr[0].length;

        int[] maxValue = new int[cols];

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                int left = 0;
                int up = 0;
                if(i > 0){
                    up = maxValue[j];
                }
                if(j > 0){
                    left = maxValue[j-1];
                }

                maxValue[j] = Math.max(up, left) + arr[i][j];
            }
        }
        return maxValue[cols-1];
    }

  
}

猜你喜欢

转载自blog.csdn.net/chenxy132/article/details/89454180
今日推荐