代码随想录打卡—day38—【DP】— 8.24 DP基础

1 DP理论基础

1.1 什么是DP

如果某一问题有很多重叠子问题,使用动态规划是最有效的。

动规是由前一个状态推导出来的,而贪心是局部直接选最优的。

1.2 DP解题步骤

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定状态转移公式 / 递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

1.3 动态规划应该如何debug

找问题的最好方式就是把dp数组打印出来,看看究竟是不是按照自己思路推导的!

做动规的题目,写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍,心中有数,确定最后推出的是想要的结果 。然后再写代码,如果代码没通过就打印dp数组,看看是不是和自己预先推导的哪里不一样。如果打印出来和自己预先模拟推导是一样的,那么就是自己的递归公式、初始化或者遍历顺序有问题了。如果和自己预先模拟推导的不一样,那么就是代码实现细节有问题。这样才是一个完整的思考过程,而不是一旦代码出问题,就毫无头绪的东改改西改改,最后过不了,或者说是稀里糊涂的过了

2 509. 斐波那契数

通过一个简单题,讲一下dp套路,AC代码:

cpp 复制代码
class Solution {
public:
    int dp[40];  // step1:确定状态数组和含义

    int fib(int n) 
    {
        dp[0] = 0;  // step3: 初始化
        dp[1] = 1;
        for(int i = 2; i <= n;i++)  // step4:确定遍历顺序
            dp[i] = dp[i-1]+dp[i-2];  // step2:确定转移函数
        return dp[n];
    }
};

3 70. 爬楼梯

70. 爬楼梯

一次做,AC代码:

疑问:怎么判断用搜索还是dp?这题,我没有受过dp训练所以第一反应是用dfs搜索,找到所有符合要求的叶子。

cpp 复制代码
class Solution {
public:
    int dp[50];    // step1:含义: 对于下标i  有多少种方案到第i层
    /*
    step2:状态转移方程 dp[i] = dp[i-2] + dp[i-1]
    step3: dp数组初始化 dp[1] = 1 , dp[2] = 2
    step4: 遍历顺序 i递增
    step5: 模拟 1,2,3(1 1 1 + 2 1 +1 2 ),5
    */ 
    int climbStairs(int n) 
    {
        // 这题我的第一感觉是搜索 什么时候用dp????
        dp[1] = 1;
        dp[2] = 2;
        for(int i = 3; i <= n; i++)
            dp[i] = dp[i-1] + dp[i-2];
        return dp[n];
    }
};

4 746. 使用最小花费爬楼梯

746. 使用最小花费爬楼梯

写简单dp题好有意思md可能是太简单,一次ac:

cpp 复制代码
class Solution {
public:
    int dp[1010]; // 第i --- 表示到达i层的最小花费
    /*
    dp[i] = min(dp[i-2]+cost[i-2],dp[i-1]+cost[i-1])
    dp[0] = 0;
    dp[1] = 0;
    增序
    模拟dp  0 0 10 15
    */
    int minCostClimbingStairs(vector<int>& cost) 
    {
        dp[0] = 0;
        dp[1] = 0;
        int i = 2;
        for(; i < cost.size();i++)
            dp[i] = min(dp[i-2]+cost[i-2],dp[i-1]+cost[i-1]);
        return min(dp[i-2]+cost[i-2],dp[i-1]+cost[i-1]);
    }
};
相关推荐
小月土星1 分钟前
LeetCode 142. 环形链表 II 超详细题解(快慢指针原理+逐行代码拆解)
算法
dok1212 分钟前
Johannes 《Linux内核模块与设备驱动开发:编写Linux驱动程序》 (11)kmalloc 动态内存分配和struct file中的私有数据
linux·驱动开发·算法
hansang_IR16 分钟前
【题解】[COCI 2024/2025 #2] 流明 / Blistavost
c++·算法·动态规划·dp
不正经学生21 分钟前
C语言指针进阶:const 和野指针——给指针加锁,向野指针宣战
c语言·开发语言·c++·算法·c#
程序喵大人22 分钟前
【C++进阶】STL算法与函数对象 - 01 让算法去处理一段迭代器范围
开发语言·c++·算法·函数对象
Keven_1126 分钟前
算法札记:二叉树前序、中序、后序遍历及对应序列重要性质
数据结构·算法·深度优先
Delite80230 分钟前
微库仑氧化法硫氯检测:油品分析中测量误差的控制要点
算法
宵时待雨36 分钟前
优选算法专题12:队列
算法·leetcode·职场和发展
tianyu2341 小时前
双指针循环匹配金额——打款记录与账单的自动对账算法
java·算法·双指针循环·匹配金额
旖旎夜光1 小时前
LeetCode 738:单调递增的数字(贪心算法) —— 题解
数据结构·c++·算法·leetcode·贪心算法