N阶楼梯上楼问题——华中科技大学

题目描述

在这里插入图片描述

知识点

动态规划

实现

码前思考

  1. 这道题给我的first impression是斐波拉契数列,就是给人以一种从小推到大的那种感觉(其实,后面发现真的就是斐波拉契数列,哭);

  2. 于是乎,我就想到了动态规划,动态规划通常是递推和递归两种方式。。题目明确指出不能用递归,我佛了,那只能递推

  3. 由于感觉是动态规划,先确定一下 dp数组的涵义和递推开始的地方是什么?

    1. dp数组的涵义:由于题目是求n个台阶的到达方式通常dp数组的涵义就是问题的求解对象,所以我们把dp数组定义为i个台阶的到达方式;
    2. 递推开始的地方:由于题目的特性,我假设是dp[1]=1,dp[2]=2,有问题后面再改吧
  4. 接下来就是最重要的寻找大问题与小问题的关系,也就是状态转移方程!

    这个过程是一个玄学的过程,感觉对于我这种🧠cannot run fast的人,我就是先到处试关系,不断纠正和想新的方式。
    我发现在i=3,对于到达i的方式,无非就是两大类——第一步是“1个台阶”;第一步是“2个台阶”。这样就顺利变成了这两大类相加,这两大类是啥呢?就是dp[i-1]和dp[i-2]🙂,over!!!这踏马不就是斐波拉契数列吗?哭了,果然我🧠不太好。。。

实现代码

//采用动态规划进行解题
//动态规划的核心之一是分解成子结构
//注意只要第一步不同,这个序列绝对不相同
//递推的开始是1和2
 
#include "bits/stdc++.h"

using namespace std;

const int maxn = 100;

//输入的整数 
int n;

//动态规划数组
//数组下标从1开始 
int dp[maxn];
 
int main(){
	//只要有输入 
	while(~(scanf("%d",&n))){
		//共享数据结构要进行初始化
		//通过分析发现,不用进行初始化
		fill(dp,dp+maxn,0);
		
		//递归的开始 
		dp[1] = 1;
		dp[2] = 2; 
		
		for(int i=3;i<=n;i++){
			for(int j=1;j<=2;j++){
				dp[i] += dp[i-j];
			}
		}
		
		printf("%d\n",dp[n]); 
	} 
	return 0;
} 
 

码后反思

  1. 关于这种由于开头或者结尾的种类可以确定,从而变成子问题求解的题目还挺多的,比如我们的LIS就是类似的吧。其实说到底,动态规划的一部分题目是这样的,因为你想呀,既然动态规划是要用子问题来解答,有时你只要把你这个大问题比子问题多的部分自己求出来,剩下的交给子问题就好了,这个多出来的部分,不就有可能是开头或者结尾吗?🙂

  2. 哈哈,看了《王道》的解答,发现它想到了 打表,是呀,这种一次计算,终身快速查询可以的!记住啦。

  3. 一个非常重要的一点—— 当N等于90的时候,可能会超出int的范围!所以用long long!!! 这是我没有考虑到的。。。修改代码如下:

    //采用动态规划进行解题
    //动态规划的核心之一是分解成子结构
    //注意只要第一步不同,这个序列绝对不相同
    //递推的开始是1和2
     
    #include "bits/stdc++.h"
    
    using namespace std;
    
    const int maxn = 100;
    
    //输入的整数 
    int n;
    
    //动态规划数组
    //数组下标从1开始 
    long long dp[maxn];
     
    int main(){
    	//递归的开始 
    	dp[1] = 1;
    	dp[2] = 2; 
    	
    	for(int i=3;i<=90;i++){
    		for(int j=1;j<=2;j++){
    			dp[i] += dp[i-j];
    		}
    	}
    	
    	//只要有输入 
    	while(~(scanf("%d",&n))){
    		printf("%lld\n",dp[n]); 
    	}
    	 
    	return 0;
    } 
     
    
  4. 所以说,写出了代码不要沾沾自喜,要去看别人怎么解题的,发现自己的不足,记住:你只是个菜鸡,你刷题是为了找到自己的不足,避免在机试中犯这种错误!

  5. 重新梳理一下动态规划的步骤——定义dp数组定义递推/递归边界状态转移方程。。。说起来简单,但是做起来真的玄学。

  6. 其实更符合动态规划的思想是最后一步是1个台阶还是两个台阶,这样更能体现动态规划的“连贯性”?

  7. 加油💪

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值