美文网首页
动态规划入门笔记(九章算法)

动态规划入门笔记(九章算法)

作者: Minority | 来源:发表于2020-02-02 16:50 被阅读0次


类型一:最值型


动态规划通常使用四个步骤来解答:

1、确定状态
2、转移方程
3、初始条件和边界情况
4、计算顺序



[图片上传中...(image.png-b17f36-1580630141799-0)]

递归的解法:

#include <iostream>
#include <cmath> 

using namespace std;

int f(int x){
    if(x==0){ return 0;}
    int res = 1000000000;  //无穷大
    
    if(x>=2){
        res = min(fun(x-2) + 1,res);
    }
    if(x>=5){
        res = min(f(x-5) + 1,res);
    }
    if(x>=7){
        res = min(f(x-7) + 1,res);
    }

    return res;
}

int main()
{   

    cout<<f(27);
    
    return 0;
}

由上图可以看出,f(20)计算了三次,f(15)计算了两次。如果让求的
递归数值比较大,就会产生很多重复的计算。


边界情况就是不要让数组越界

计算顺序大多数情况都是从小到大,二维的话就是从上到下,从左到右。









动态规划解法:

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {

        //初始化状态数组
        vector<int> f(amount+1);
        int coin_num = coins.size();

        //初始条件
        f[0] = 0;
        int i,j;

        //从小到大计算每个值的值,便于递归使使用,返回最后一个需要的值,即f(amount)的值
        for(int i = 1;i<=amount;i++){
            //刚开始初始化为无穷大
            f[i] = INT_MAX;

            //计算“最后一枚”:f[i] = min(f[i-coin[0]] + 1,....,f[i-coin[n-1] + 1])
            for(int j=0;j<coin_num;j++){
                //保证要计算的值必须大于硬币的面额 && 需要的硬币的个数不能为正无穷,否则加1后溢出(防溢出)
                if(i>=coins[j] && f[i - coins[j]] != INT_MAX){
                    f[i] = min(f[i - coins[j]] + 1,f[i]);
                }
            }
        }

        if(f[amount] == INT_MAX){
            f[amount] = -1;
        }

        return f[amount];        
    }
};

类型二:计数型



  • 之所以可以使用X+Y,是因为机器人只能向右或向下走,满足“不重复、无遗漏”条件。
  • 为什么把原文问题“走到(m-1,n-1)”变成“走到(m-2,n-1)和(m-1,n-2)”就代表分解成了子问题?



    由上图可以看出,矩阵是变小了。


class Solution {
public:
    int uniquePaths(int m, int n) {

        //开辟二维数组保存状态:因为最后为(m-1,n-1),所以数组大小为m*n,不用再行列加1
        int f [m][n];

        for(int i=0; i<m; i++){              //从上到下
            for(int j=0; j<n; j++){
                if(i==0 || j==0){            //从左到右
                    //出口:边界条件
                    f[i][j] = 1;
                }
                else{
                    //更新(i,j)位置的状态:可以使用加法来分别表示两个方向的更新(上和左)
                    f[i][j] = f[i-1][j] + f[i][j-1];
                }
            }
        }

        return f[m-1][n-1];
        
    }
};
  • 注意:确定顺序为从上到下,从左到右的根本原理是利用前面的计算结果。

类型三:可行性型(是否存在型)



class Solution {
public:
    bool canJump(vector<int>& nums) {
        
        //初始化状态数组
        int n = nums.size();
        bool f[n];

        //初始化初始变量    
        f[0] = true;

        for(int i = 1; i<n; i++){
            f[i] = false;
            for(int j = 0; j<i; j++){                
                if(f[j] && (nums[j] + j >= i)){
                    f[i] = true;
                }
            }
        }

        return f[n-1];
    }
};

相关文章

  • 动态规划入门笔记(九章算法)

    类型一:最值型 动态规划通常使用四个步骤来解答:1、确定状态2、转移方程3、初始条件和边界情况4、计算顺序 递归的...

  • DP入门 || 未完待续

    今天学一下逃避了一年的dp= = 以下内容整理自九章算法—dp入门 动态规划的类型 计数 + *计数路径(遍历路...

  • 算法与数据结构网址备忘

    kd-tree算法原理与开源代码实现 详解kd-tree 动态规划入门篇 动态规划进阶篇

  • 4. 动态规划算法

    1. 动态规划算法总结2. 漫画:什么是动态规划?3.算法之动态规划4. 动态规划-算法

  • Swift 算法实战:动态规划

    Swift 算法实战:动态规划 Swift 算法实战:动态规划

  • 动态规划

    链接:很特别的一个动态规划入门教程动态规划与贪心算法的区别与联系 那么遇到问题如何用动态规划去解决呢?根据上面的分...

  • 程序员算法基础——动态规划

    程序员算法基础——动态规划 程序员算法基础——动态规划

  • 动态规划

    --tags: 算法,动态规划 动态规划解题 引入:动态规划 和贪心法 都是算法的思想方法 贪心算法——像 第一类...

  • 《算法图解》note 9 动态规划

    这是《算法图解》的第九篇读书笔记,主要内容是动态规划的简介。 1.动态规划定义 动态规划指的是在约束条件下,将问题...

  • 动态规划 Dynamic Programming

    从运筹学和算法的角度综合介绍动态规划 算法分类总结动态规划与静态规划的关系浅析静态规划和动态规划动态规划解非线性规...

网友评论

      本文标题:动态规划入门笔记(九章算法)

      本文链接:https://www.haomeiwen.com/subject/gkjqxhtx.html