1.青蛙跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。剑指 Offer 10- II. 青蛙跳台阶问题 - 力扣(LeetCode)
假设跳到第n级台阶的跳数我们定义为f(n),很显然就可以得出以下公式:
f(10)=f(9)+f(8)
f(9)=f(8)+f(7)
f(8)=f(7)+f(6)
........
f(3)=f(2)+f(1)
即公式为:f(n)=f(n-1)+f(n-2)
那f(2) 或者 f(1) 等于多少呢?
当只有2级台阶时,有两种跳法,第一种是直接跳两级,第二种是先跳一级,然后再跳一级。即f(2) = 2;当只有1级台阶时,只有一种跳法,即f(1)= 1;
有两种方法解决这个问题:1.递归(自顶向下) 2.动态规划(自底向上)
动态规划有几个典型特征,最优子结构、状态转移方程、边界、重叠子问题。在青蛙跳阶问题中:
f(n-1)和f(n-2) 称为 f(n) 的最优子结构
f(n)= f(n-1)+f(n-2)就称为状态转移方程
f(1) = 1, f(2) = 2 就是边界
比如f(10)= f(9)+f(8),f(9) = f(8) + f(7) ,f(8)就是重叠子问题
class Solution {
public:
int numWays(int n)
{
if(n<=1) return 1;
if(n==2) return 2;
int a=2;
int b=1;
int temp;
for(int i=3;i<=n;i++)
{
temp=(a+b)%1000000007;
b=a;
a=temp;
}
return temp;
}
};
2.杨辉三角
(1) 划分阶段
按照行数进行阶段划分。
(2)定义状态
定义状态 dp[i][j] 为:杨辉三角第 i 行、第 j 列位置上的值。
(3)状态转移方程
根据观察,很容易得出状态转移方程为:,此时。
4. 初始条件
每一行第一列都为 1,即 dp[i][0] = 1。
每一行最后一列都为 1,即 dp[i][i] = 1。
class Solution {
public:
vector<vector<int>> generate(int numRows)
{
vector<vector<int>> result(numRows);
if (numRows >= 1) result[0].emplace_back(1);
if (numRows >= 2) {
result[1].emplace_back(1);
result[1].emplace_back(1);
}
for(int i=2;i<=numRows-1;i++)
{
result[i].emplace_back(1);
for (int j = 1; j <= i - 1; j++) {
result[i].emplace_back(result[i - 1][j] +result[i - 1][j - 1]);
}
result[i].emplace_back(1);
}
return result;
}
};