[Introduction to dynamic programming] five steps of dynamic programming ideas_Fibonacci_climbing stairs_minimum cost climbing stairs


Five steps of dynamic programming

1. Determine the meaning of dp and dp[i]
2. Find out the recursive formula
3. Determine how to initialize the dp array
4. Determine the traversal order
5. Print the dp array for verification

1. Fibonacci sequence

click me directly~
insert image description here

Idea: dynamic programming solution

Five steps of dynamic programming:

1. Determine the meaning of dp and dp[i]
2. Find out the recursive formula
3. Determine how to initialize the dp array
4. Determine the traversal order
5. Print the dp array for verification

  • 1. The meaning of dp and dp[i]:
    According to the requirements of the topic, the nth Fibonacci sequence is required, then the i-th Fibonacci number is dp[i]

  • 2. Recursion formula:
    dp[i] = dp[i-1] + dp[i-2]

  • 3. Initialization:
    dp[0] = 0, dp[1] = 1

  • 4. Determine the traversal order
    According to the recursive formula, the i-th Fibonacci number is derived from the i-1 and i-2 numbers.
    So you need to traverse from front to back.

  • 5. Print out the dp array to verify whether the recursive formula is correct,
    just print it in the solution.
    0 1 1 2 3 5 8 13 21 34 55…

The specific code is as follows:

class Solution {
    
    
public:
//动态规划解题五步骤
//1.dp数组及其下标的含义
//dp数组是记录斐波那契数列每一个数字,下标i对应第i个
//2.递推公式
//dp[i] = dp[i-1] + dp[i-2];
//3.如何初始化dp数组
//dp[0] = 0,dp[1] = 1
//4.确定遍历顺序
//从前往后遍历
//5.举例推导dp数组

    int fib(int n) 
    {
    
    
        if(n<2)
            return n;
        vector<int> dp(n+1);
        dp[0] = 0,dp[1] = 1;
        for(int i = 2;i<=n;++i)
        {
    
    
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
};

时间复杂度O(n),空间复杂度O(n)

2. Climb the stairs

click me directly~

insert image description here

Idea: dynamic programming

Five steps of dynamic programming:

1. Determine the meaning of dp and dp[i]
2. Find out the recursive formula
3. Determine how to initialize the dp array
4. Determine the traversal order
5. Print the dp array for verification

  • 1. It can be seen from the meaning of the question that there is one way to climb one staircase, but there are two ways to climb two stairs.

Then there are dp[i] ways to climb i stairs.

  • 2. Recursion formula

Obviously we can know that to climb the i-th staircase, there must be only two situations:

    • (1) Climb 1 step up from the i-1th staircase
    • (2) Climb 2 steps from the i-2th staircase to climb to the i-1st staircase. There are dp[i-1] ways to climb to the i-2th staircase. There are dp[i -2] ways so: dp[i] = dp[i-1] + dp[i-2]
  • 3. The dp array is initialized. According to the recursive formula, any first-order staircase is obtained from its first two.

So all stairs start with the first and second steps.
dp[1] = 1, dp[2] = 2; for the 0th step stairs, it doesn't make sense.

  • 4. Traversal order

traverse from front to back

  • 5. Just print the dp array

0 1 1 2 3 5 8 13 21 34 55…

The specific code is as follows:

class Solution {
    
    
public:
//动态规划五部曲
//1.确定dp以及dp[i]的含义
//dp[i]:爬到第i层楼梯有dp[i]种方法
//2.确定递推公式
//dp[i] = dp[i-1] + dp[i-2]
//3.如何初始化
//dp[0]无意义,不初始化,dp[1] = 1,d[2] = 2;
//4.如何进行遍历
//由递推公式可知,第dp[i]是由dp[i-1] 和dp[i-2]得来的,所以需要从前往后遍历
//5.打印dp数组出来验证结果
    int climbStairs(int n) 
    {
    
    
        if(n < 3)
            return n;
        vector<int> dp(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];
    }
};

时间复杂度O(n),空间复杂度O(n)

3. Use the minimum cost to climb the stairs

click me directly~

insert image description here

Idea: dynamic programming

Five steps of dynamic programming:

1. Determine the meaning of dp and dp[i]
2. Find out the recursive formula
3. Determine how to initialize the dp array
4. Determine the traversal order
5. Print the dp array for verification

According to the question, we can know that we can choose to start climbing the stairs from the steps with subscript 0 or subscript 1. No matter which one we choose, we don’t consume stamina. Only when we climb up will we consume the stamina value of the current subscript i. cost[i].

insert image description here

Obviously we can know that to climb the i-th staircase, there must be only two situations:

    • (1) Climb 1 step up from the i-1th staircase
    • (2) Climb up 2 steps from the i-2th staircase

To climb up from the i-1st stair, the physical strength value required is: cost[i-1]
To climb up from the i-2th staircase, the physical strength value required to be spent is: cost[i-2]
We only It is necessary to
obtain the minimum value of the physical strength dp[i-1]+cost[i-1] to the i-1th floor and the physical strength dp[i-2]+cost[i-2] to the i-2th floor That's it.

Then, according to the five steps of dynamic programming:

  • 1. Determine the meaning of dp and dp[i]:

dp[i] indicates that the stamina value paid for climbing to the i-th step is dp[i]

  • 2. Recursion formula

dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])

  • 3. How to initialize

Since choosing stairs does not consume stamina, then dp[0] = 0, dp[1] = 0
(please see the meaning of dp[i], which is the stamina value)

  • 4. How to traverse

According to the recursive formula, we need to traverse from front to back

  • 5. Print out the dp array

insert image description here

The specific code is as follows:

class Solution {
    
    
public:
//动态规划五部曲:
//1.确定dp及dp[i]的含义
//dp[i]:到达第i个位置的最小花费为dp[i]

//2.递推公式
//dp[i] = min(dp[i-1] + cost[i-1],dp[i-2] + cost[i-2]);
//有dp[i]的含义可知,dp[i-1]的含义是到达第i-1个位置的最小花费。
//3.如何初始化
//我们可以选择从0或者1的台阶开始爬楼梯,说明选择任意一个楼梯是不花费体力的。所以dp[0] = 0,dp[1] = 1;
//4.如何进行遍历
//由递推公式可知,遍历应该从前往后遍历。
//5.打印dp数组验证递推公式是否正确
    int minCostClimbingStairs(vector<int>& cost) 
    {
    
    
        int n = cost.size();
        vector<int> dp(n+1);
        dp[0] = 0,dp[1] = 0;

        for(int i = 2;i<=n;i++)
        {
    
    
            dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
            cout << dp[i] << endl;
        }

        return dp[n];
    }
};

时间复杂度O(n),空间复杂度O(n)

Summarize

I started to learn dynamic programming algorithms today, and I gained a lot.

Guess you like

Origin blog.csdn.net/2301_76496134/article/details/131352522