我是靠谱客的博主 搞怪镜子,这篇文章主要介绍算法-动态规划-跳台阶,现在分享给大家,希望可以做个参考。

leetcode中有一个类型的题目是动态规划经常考察的点——斐波那契数列。跳台阶的问题是斐波那契数列的变种问题,总体思路上没有什么太大变化。

1.跳台阶easy

先来看这道题剑指 Offer 10- II. 青蛙跳台阶问题。题目描述如下:

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:
输入:n = 2
输出:2

示例 2:
输入:n = 7
输出:21

示例 3:
输入:n = 0
输出:1
提示:0 <= n <= 100
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

根据题意可得:

  • 台阶数小于1,则跳的方案为0
  • 台阶数等于1,方案数为1
  • 台阶数等于2,方案数为2,可以跳一阶两次,或者可以跳二阶一次
  • 当台阶数大于2,方案数的递推公式为:
    d p [ i ] = d p [ i − 1 ] + d p [ i − 2 ] dp[i] = dp[i - 1] + dp[i - 2] dp[i]=dp[i1]+dp[i2]
    也就是说要想跳上当前台阶 i i i,需要从它的 i − 1 i - 1 i1或者 i − 2 i - 2 i2阶跳上来。
    那么核心代码为:
#include<iostreaam>
#include<vector>
using namespace std;
class Solution{
public:
public:
int numWays(int n) {
if(n <= 1)
{
return 1;
}
int n_1 = 1;
int n_2 = 1;
int x = 1000000007;
for(int i = 2;i <= n;i++)
{
n_1 = n_1 + n_2;
n_2 = n_1 - n_2;
n_1 = n_1 %x;
n_2 =n_2 %x;
}
return n_1;
}
};

注意方案数过大时需要取模。

2. 掷骰子middle

掷骰子游戏相比于跳台阶游戏其实并无太大差别,主要是方案数增多。原来跳台阶只能跳一阶或者两阶,方案数为最多为2。而掷骰子则方案数一下子增加到6。先来看题目:

骰子的点数有1-6点,掷骰子得到每个面的概率都是1/6,。现在我们要掷出某个点数 N ( 1 < = N < = 30 ) N(1 <= N <= 30) N1<=N<=30),可能的方案数有多少?注意:掷出点数1,2和2,1本质上是两种不同的方案
示例1:N = 3
输出:4
解释:可能的方案数为: ( 1 , 1 , 1 ) , ( 1 , 2 ) , ( 2 , 1 ) , ( 3 ) (1,1,1), (1, 2), (2, 1), (3) (1,1,1),(1,2),(2,1),(3),总的方案数有四种

根据题目信息可得,如果要想达到某个点数(台阶),可能的方案数从上一题的两种变成了现在的六种。

  • 如果是点数N小于等于6:

d p [ N ] = d p [ N − 1 ] + d p [ N − 2 ] + . . . + d p [ N − i ] , i < = N dp[N] = dp[N - 1] + dp[N - 2] + ...+dp[N - i],i <= N dp[N]=dp[N1]+dp[N2]+...+dp[Ni],i<=N

  • 如果点数N大于6

d p [ N ] = d p [ N − 1 ] + d p [ N − 2 ] + d p [ N − 3 ] + d p [ N − 4 ] + d p [ N − 5 ] + d p [ N − 6 ] dp[N] = dp[N-1] + dp[N- 2] + dp[N - 3] + dp[N - 4] + dp[N- 5] + dp[N- 6] dp[N]=dp[N1]+dp[N2]+dp[N3]+dp[N4]+dp[N5]+dp[N6]

如果点数小于等于6,那么就可以方案数就是已经存在的方案数之和。例如掷出点数3,那么可以从 d p [ 3 − 1 ] + d p [ 3 − 2 ] + d p [ 3 − 3 ] = d p [ 2 ] + d p [ 1 ] + d p [ 0 ] dp[3 - 1] + dp[3 - 2] + dp[3 - 3] = dp[2] + dp[1] + dp[0] dp[31]+dp[32]+dp[33]=dp[2]+dp[1]+dp[0]三者之和了。

如果指出点数大于6,那么方案数就是掷出点数的六种组合的结果。

上面这种考虑方式其实已经包含了掷出不同点数(顺序不同的)的组合了。

实际代码如下:

#include<iostream>
#include<vector>
using namespace std;
static int getNum(int N)
{
if(N <= 1)
{
return 1;
}
vector<int>dp(N + 1, 0);
dp[0] = 1;//点数为0的组合有一个
dp[1] = 1;//点数为1的组合有一个
for(int i = 2;i <= N;++i)
{
for(int j = 1;j <= 6 && i - j >= 0;++j)
{
dp[i] += dp[i - j];
}
}
return dp[N};
}
int main()
{
int N;
cin >> N;
cout << getNum(N) << endl;
return 0;
}

最后

以上就是搞怪镜子最近收集整理的关于算法-动态规划-跳台阶的全部内容,更多相关算法-动态规划-跳台阶内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部