Article Directory
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
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
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
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].
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
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.