基本题型之动态规划

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.杨辉三角

118. 杨辉三角 - 力扣(LeetCode)

(1) 划分阶段
按照行数进行阶段划分。

(2)定义状态
定义状态 dp[i][j] 为:杨辉三角第 i 行、第 j 列位置上的值。

(3)状态转移方程
根据观察,很容易得出状态转移方程为:dp[i][j] = dp[i-1][j-1] + dp[i-1][j],此时i> 0 ,j > 0

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;
    }
};

猜你喜欢

转载自blog.csdn.net/mabaizi/article/details/128885215
今日推荐