509. 斐波那契数
动态规划中每一个状态是由上一个状态推导出来的:重叠子问题
(贪心:每次选取最大/最小的,与上一个状态无关)
动规五部曲
动态规划debug
509. 斐波那契数:
力扣
70. 爬楼梯
力扣
746. 使用最小花费爬楼梯
力扣
给你一个整数数组 cost
,其中 cost[i]
是从楼梯第 i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。你可以选择从下标为 0
或下标为 1
的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。
class Solution {
public:
int minCostClimbingStairs(vector& cost) {
int dp[2];
dp[0] = cost[0], dp[1] = cost[1];
int cur;
for(int i = 2; i < cost.size(); i++){
cur = min(dp[0], dp[1]) + cost[i];
dp[0] = dp[1];
dp[1] = cur;
}
return min(dp[0], dp[1]);
}
};
力扣
一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。总共有多少条不同的路径?
class Solution {
public:
int uniquePaths(int m, int n) {
int* dp = new int[n + 1];
dp[0] = 0;
for(int i = 1; i < n + 1; i++){
dp[i] = 1;
}
for(int j = 1; j < m; j++){
for(int i = 1; i < n + 1; i++){
dp[i] = dp[i] + dp[i - 1];
}
}
return dp[n];
}
};
数论方法:组合数 代码随想录
一共m + n - 2步,其中m - 1步向下,n - 1步向右
方法数:
力扣
一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
网格中有障碍物,网格中的障碍物和空位置分别用 1
和 0
来表示。从左上角到右下角将会有多少条不同的路径?
class Solution {
public:
int uniquePathsWithObstacles(vector>& obstacleGrid) {
int m = obstacleGrid.size(), n = obstacleGrid[0].size();
int dp[101];
for(int i = 0; i <= n; i++){ // line 0
dp[i] = 0;
}
dp[1] = 1;
for(int j = 1; j <= m; j++){ // line 1 -> m
for(int i = 1; i <= n; i++){ // row 1 -> n
if(obstacleGrid[j - 1][i - 1]) dp[i] = 0;
else dp[i] = dp[i] + dp[i - 1];
}
}
return dp[n];
}
};
力扣
给定一个正整数 n
,将其拆分为 k
个 正整数 的和( k >= 2
),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
class Solution {
public:
int integerBreak(int n) {
int dp[60]; //dp[i]: max score of split i
dp[0] = 0, dp[1] = 1;
for(int i = 2; i <= n; i++){
dp[i] = 0;
for(int j = 1; j < i; j++){
dp[i] = max(dp[i], j * dp[i - j]);
dp[i] = max(dp[i], j * (i - j));
}
cout << i << " " << dp[i] << endl;
}
return dp[n];
}
};
解法:
转化为动态规划
拆分成多个整数 => 拆分成两个整数,再逐步拆分成多个
如9 = 3 + 3 + 3,可以看做先拆分成9 = 3 + 6, 再拆分6 = 3 + 3,因此9的状态依赖3的状态和6的状态。
dp[i]:整数i拆分成2个或多个整数时,乘积的最大值
每次迭代,j遍历1到i-1,判断拆分成j和i-j时的乘积是否比当前大
优化:只遍历到i/2(因为尽量拆成相同的数)
解法2:(需要证明)
拆成n个3,如果除不尽保留4
力扣
给你一个整数 n
,求恰由 n
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
class Solution {
public:
int numTrees(int n) {
int dp[20]; // tree num of n_node = i
dp[0] = 1, dp[1] = 1, dp[2] = 2;
for(int i = 3; i <= n; i++){ // n_node = i
dp[i] = 0;
for(int j = 1; j <= i; j++){ // root = j
dp[i] = dp[i] + dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
};