剑指Offer-题47(Java版):礼物的最大价值

参考自:《剑指Offer——名企面试官精讲典型编程题》

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

主要思路:使用动态规划,f(i,j)表示到达坐标[i,j]时能拿到的最大礼物总和。则当前格子f(i,j)可由左边格子f(i-1,j)或f(i,j-1)上面格子到达。因此,递归式子为:
f ( i , j ) = m a x ( f ( i − 1 , j ) , f ( i , j − 1 ) ) + g i f t [ i , j ] , f(i,j) = max(f(i-1,j),f(i,j-1))+gift[i,j], f(i,j)=max(f(i1,j),f(i,j1))+gift[i,j]
其中,gift[i,j]=坐标[i,j]格子里的礼物

关键点:动态规划

时间复杂度:O(m×n)

public class MaxValueOfGifts {
    public static void main(String[] args) {
        int[][] values = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}};
        //29
        System.out.println(getMaxPathValue(values));
        int[][] values1 = {{1, 10, 3, 8}};
        //22
        System.out.println(getMaxPathValue(values1));
        int[][] values2 = {
                {1},
                {1},
                {5},
                {3}};
        //10
        System.out.println(getMaxPathValue(values2));
    }

    private static int getMaxPathValue(int[][] values) {
        if (values == null) {
            return 0;
        }

        int rows = values.length;
        if (rows <= 0) {
            return 0;
        }
        int cols = values[0].length;
        if (cols <= 0) {
            return 0;
        }

        int[][] maxValues = new int[rows][cols];
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                //左边
                int fromLeft = 0;
                //上面
                int fromUp = 0;
                if (i > 0) {
                    fromUp = maxValues[i - 1][j];
                }
                if (j > 0) {
                    fromLeft = maxValues[i][j - 1];
                }

                maxValues[i][j] = Math.max(fromLeft, fromUp) + values[i][j];
            }
        }
        return maxValues[rows - 1][cols - 1];
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值