经典动态规划-从DFS到递归转迭代+剪枝(经典动态规划)

前言

动态规划思想如何得到?为什么以下就想到动态规划?可以先DFS打个基础,然后体会其中的缺点,然后剪枝改进,递归再转迭代,那么就是经典的动态规划了。

一、礼物最大价值

在这里插入图片描述

二、DFS演变成动态规划

1、DFS

//礼物的最大价值
public class MaxValue {
    /*
    路径上能拿到的礼物的总价值最大为多少?
    1.如何走完一条路径?有起点有终点,component-DFS完成路径上的礼物收集。
    2.如何拿到最大价值?记录最大价值,每次到一条路径的终点时更新最大价值。
    总结:component-DFS + 记录最大值。
     */
    public int maxValue(int[][] grid) {
        dfs(grid, 0, 0, 0);

        return maxValue;
    }

    private void dfs(int[][] grid, int i, int j, int value) {
        int m = grid.length, n = grid[0].length;

        value += grid[i][j];

        if (i == m - 1 && j == n - 1) {
            if (maxValue < value) maxValue = value;

            return;
        }
        //向右走
        if (j + 1 < n) dfs(grid, i, j + 1, value);
        //向下走
        if (i + 1 < m) dfs(grid, i + 1, j, value);
    }

    int maxValue = 0;//最大礼物价值
}

2、DFS+剪枝

/*
改进
问题所在:有些共同路径被多次访问,但是由于需走到终点去更新maxValue,所以会重复走很多次,所以需要剪枝。
如何剪枝?-idea:如果知道以该点做为终点,找到了最大价值,那么其它路过来发现价值比其低,就没必要走接下来的公共路径了。
右下走,那么取左上来的最大值,要么走上面来的路径,要么走左边来的路径,这样就进行了剪枝,避免不必要走的重复公共路径。
用空间换时间,记录上和左的最大价值,然后获得当前位置的最大价值,通过Math.max来剪掉一条路径。
 */
class MaxValue2 {
    //递归转迭代,用空间记录来剪枝。
    public int maxValue(int[][] grid) {
        int m = grid.length, n = grid[0].length;

        for (int i = 1; i < m; i++) grid[i][0] += grid[i - 1][0];
        for (int i = 1; i < n; i++) grid[0][i] += grid[0][i - 1];

        for (int i = 1; i < m; i++)
            for (int j = 1; j < n; j++)
                grid[i][j] += Math.max(grid[i - 1][j], grid[i][j - 1]);

        return grid[m - 1][n - 1];
    }

}

总结

1)DFS
2)递归转迭代+如何剪枝?
3)动态规划

参考文献

[1] LeetCode 礼物最大价值

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值