道阻且长,行则将至,走慢一点没关系,不停下就好了.|

Ac_c0mpany丶

园龄:3年7个月粉丝:6关注:3

动态规划

动态规划

动态规划是一种解决多阶段决策问题的优化方法,把多阶段转化为一系列但阶段问题,利用各阶段之间的关系,逐个求解。

1.动态规划问题的解法

确定遍历顺序:逆序遍历、顺序遍历

2.动态规划问题的性质

能采用动态规划求解的问题的一般要具有3个性质:

  1. 最优性原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优性原理。
  2. 无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。
  3. 有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势)。

3.动态规划问题“五部曲"

  1. 确定dp数组以及下标含义
  2. 确定递推公式
  3. 初始化dp数组
  4. 确定遍历顺序
  5. 举例推导pd数组

LeetCode70.爬楼梯

1. 确定dp数组以及下标含义
	dp[i]:爬到第i层楼,有dp[i]种方法
2. 确定递推公式
	dp[i]可以有两个方向推导出来
	首先是dp[i - 1],上到第i-1层楼梯,有dp[i-1]种方法,那么再跳一个台阶就是dp[i]
	还有就是dp[i - 2],上到第i-2层楼梯,有dp[i-2]种方法,那么再跳两个台阶就是dp[i]
	所以dp[i] = dp[i - 1] + dp[i - 2]
3. 初始化dp数组
	dp[1] = 1
	dp[2] = 2
4. 确定遍历顺序
	顺序遍历
5. 举例推导pd数组
	1 2 3 4 5 8 13(斐波那契数列的变种) 
class Solution {
    public int climbStairs(int n) {
        if (n <= 2) return n;
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i ++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

LeetCode746. 使用最小花费爬楼梯

1.确定dp数组以及下标含义
	dp[i]表示爬上第i个台阶需要支付的最低费用
2.确定递推公式
	dp[i]可以由dp[i - 2]爬2阶到达
	dp[i]可以由dp[i - 1]爬1阶到达
	dp[i] = min(dp[i - 2] + cost[i - 2], dp[i - 1] + cost[i - 1])
3.初始化dp数组
	dp[0] = dp[1] = 0
4.确定遍历顺序
	顺序遍历
5.举例推导dp数组
	求dp[cost.length]
class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int[] dp = new int[cost.length + 1];
        dp[0] = 0;
        dp[1] = 0;
        for (int i = 2; i <= cost.length; i ++) {
            dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[cost.length];
    }
}

LeetCode62. 不同路径

1.确定dp数组以及下标含义
	dp[i][j]:表示从(0,0)到(i,j)有dp[i][j]条路径
2.确定递推公式
	dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
3.初始化dp数组
	处理边界
	for(int i = 0; i < m; i ++) dp[i][0] = 1;
	for(int j = 0; j < n; j ++) dp[0][j] = 1;
4.确定遍历顺序
	顺序遍历
5.举例推导dp数组
	求dp[m - 1][n - 1]
class Solution {
    public int uniquePaths(int m, int n) {
        //step1: dp[i][j]表示从(0,0)出发到(i,j)有dp[i][j]条不同的路径
        int[][] dp = new int[m][n]; 
        
        //step2: 初始化dp数组
        for (int j = 0 ; j <= n - 1; j ++) dp[0][j] = 1;
        for (int i = 0; i <= m - 1; i ++) dp[i][0] = 1;

        //step3: 递推公式
        for (int i = 1; i <= m - 1; i ++) {
            for (int j = 1; j <= n - 1; j ++) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m - 1][n - 1];
    }
}

LeetCode63. 不同路径II

1.确定dp数组以及下标含义
	dp[i][j]:表示从(0,0)到(i,j)有dp[i][j]条路径
2.确定递推公式
	dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
	若遇到障碍物,则把此障碍物初始化为0
3.初始化dp数组
	处理边界
	for(int i = 0; i < m; i ++) dp[i][0] = 1;
	for(int j = 0; j < n; j ++) dp[0][j] = 1;
	若在边界遇到障碍物,则边界上的障碍物和障碍物后面的单元格都初始化为0
4.确定遍历顺序
	顺序遍历
5.举例推导dp数组
	求dp[m - 1][n - 1]
class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        // 获取二维数组的行数和列数
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;

        int[][] dp = new int[m][n];
       
        // 初始化dp数组
        for (int i = 0; i < m; i ++) {
            //如果[i][0]是障碍物,那障碍物以及障碍物以后的单元格都初始化为0
            if (obstacleGrid[i][0] == 1) {
                break;
            }
            dp[i][0] = 1; // 否则初始化为1
        }
        for (int j = 0; j < n; j ++) {
            //如果[0][j]是障碍物,那障碍物以及障碍物以后的单元格都初始化为0
            if (obstacleGrid[0][j] == 1) {
               break;
            }
            dp[0][j] = 1;
        }

        for (int i = 1; i < m; i ++) {
            for (int j = 1; j < n; j ++) {
                if (obstacleGrid[i][j] != 1) {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; 
                } else {
                    dp[i][j] = 0;
                } 
            }
        }
        return dp[m - 1][n - 1];
    }
}

本文作者:Ac_c0mpany丶

本文链接:https://www.cnblogs.com/keyongkang/p/16337339.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Ac_c0mpany丶  阅读(82)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 You Are My Sunshine REOL
You Are My Sunshine - REOL
00:00 / 00:00
An audio error has occurred.

作曲 : Traditional

You are my sunshine

My only sunshine.

You make me happy

When skies are gray.

You'll never know, dear,

How much I love you.

Please don't take my sunshine away

The other night, dear,

When I lay sleeping

I dreamed I held you in my arms.

When I awoke, dear,

I was mistaken

So I hung my head and cried.

You are my sunshine,

My only sunshine.

You make me happy

When skies are gray.

You'll never know, dear,

How much I love you.

Please don't take my sunshine away.

You are my sunshine,

My only sunshine

You make me happy

When skies are gray.

You'll never know, dear

How much I love you

Please don't take my sunshine away

Please don't take my sunshine away.

Please don't take my sunshine away.