算法笔记--动态规划--爬楼梯问题

很经典的小问题,一个人爬楼梯,一次只能爬一阶或两阶,当总共有n阶楼梯时,有几种爬法。

这是一道很明显的递归题目,且无法像一般的动态规划那样列出递推方程,但是思想和动态规划比较类似,从问题的结果出法,逆推整个流程。

思路是这样的,这个人最后成功爬上第n阶之前,只有两种可能,爬了一阶或者两阶,因此此时他总共可拥有的次数,即为他最后爬了一阶情况下原来n-1阶的次数加上最后爬了两阶时原来n-2阶的次数。用这种思路一直向前推,直到原来n-1或n-2为一阶或两阶的情况,这时我们可以计算n=1时,只有一种情况,n=2有两种情况(一下爬了两阶,两次都爬一阶),这就是此递归的结尾。

如果把递归式子写出来,就是dp[n] = dp[n-1] + dp[n-2]

和动态规划递推式子不同的是,这里的dp[]无法在循环中得到值,只能在一次次自我调用中获得数值,因此数组就变成了可以传值的函数,这也是递推和递归的一种巧妙的转变吧。

以下代码用dp[]作为储存子问题最优解(子问题总共的次数)的数组,f()是用来判断的数组。

#include<iostream>
using namespace std;

int dp[50];
int f(int n){
	if(n == 1||n == 2){
		return n;
	}
	else{
		if(!dp[n-1]) {
			dp[n-1] = f(n-1);
		}
		if(!dp[n-2]){
			dp[n-2] = f(n-2);
		} 
		return f(n-1) + f(n-2);
	}
}



int main(){
	int n, sum;
	cout<<"请输入楼梯总数:";
	cin>>n;
	sum = f(n);
	cout<<"总共有"<<sum<<"种走法"<<endl;
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/legendary_idiot/article/details/80193704