计蒜客第16题---爬楼梯

来源:互联网 发布:玄天问道源码单机论坛 编辑:程序博客网 时间:2024/05/21 14:58

假设你现在正在爬楼梯,楼梯有n级。每次你只能爬1级或者2级,那么你有多少种方法爬到楼梯的顶部?
格式:
第一行输入一个数n(n<=50),代表楼梯的级数。
接下来一行输出你的方法总数。
样例1
输入:
5
输出:
8
很容易想到这道题可以用递归的方法:
分析:假设从底走到第n级的走法有f(n)种,走到第n级有两个方法,一个是从(n-1)级走一步,另一个是从第(n-2)级走两步,前者有f(n-1)种方法,后者有f(n-2)种方法,所以有f(n)=f(n-1)+f(n-2),还有f(0)=1,f(1)=1.
具体实现:

#include<iostream>using namespace std;int f(int n) {  if(n==0 || n==1)    return 1;  else    return f(n-1)+f(n-2);}int main() {  int n;  cout << f(n) << endl;  return 0;}

可惜会超时。
改进的方法:动态规划!
在递归思想的基础下,我们知道存在子问题求解的重复性,运用动规,只需要将子问题求解一次,以后再遇到,直接调用,所以我们新建一个数组用于存储子问题的结果:
将数组元素初始为零,若为新的子问题,我们求解,并把结果赋给对应的数组元素;这样当我们再次遇到相同的子问题,就可以直接调用了。
具体的实现:

#include<iostream>using namespace std;int result[100];int f(int n) {  int res;  if(result[n]>0)    //如果大于零,说明该子问题原来已经求过解    return result[n];   //直接返回对应的数组元素  if(n==0 || n==1)    res=1;  else    res=f(n-1)+f(n-2);  result[n]=res;  //每次都将求过解的子问题赋给对应数组元素  return res;}int main() {  int i, n;  cin >> n;  for(i=0;i<=n;i++)    result[i]=-1;  cout << f(n);  return 0;}

一位朋友提供的方法:
原理:http://blog.sina.com.cn/s/blog_6ea2c6a20100x359.html

#include<iostream>using namespace std;struct matrix {  int a, b, c, d;  matrix(int a_ = 1, int b_ = 1, int c_ = 1, int d_ = 0) {    a = a_, b = b_, c = c_, d = d_;  }};static matrix result(1, 0, 1, 0);matrix operator* (matrix x, matrix y) {  matrix r;  r.a = x.a * y.a + x.b * y.c;  r.b = x.a * y.b + x.b * y.d;  r.c = x.c * y.a + x.d * y.c;  r.d = x.c * y.b + x.d * y.d;  return r;}void mul(matrix base, int index) {  while (index != 0) {    if(index % 2) result = result * base;    base = base * base;    index /= 2;  }}int main() {  int n;  cin >> n;  matrix base(1, 1, 1, 0);  if (n == 1) {cout << 1; return 0; }  mul(base, n - 1);  cout << result.a + result.b << endl;  return 0;}

本文为转载,原文地址:http://m.blog.csdn.net/blog/SYSU_Winky/38077771

0 0
原创粉丝点击