上台阶
题目描述
现在小瓜想走上一个一共有n级的台阶,由于小瓜的腿比较短,他一次只能向上走1级或者2级台阶。小瓜想知道他有多少种方法走上这n级台阶,你能帮帮他吗?
输入
一行一个整数n(n<=100000),表示一共有n级台阶。
输出
一行一个整数,表示小瓜上台阶的方案数对100003取余的结果。
输入样例
3
输出样例
3
分析
我们采用递归的算法
代码1:
计算原理:sum(n)=sum(n-1)+sum(n-2)
#include<cstdio>
#include<iostream>
using namespace std;
typedef unsigned long long ull;
const int mod=100003;
ull sum(ull n)
{
if(n==1) return 1;
if(n==2) return 2;
else return sum(n-1)+sum(n-2);
}
int main()
{
ull n;
scanf("%lld",&n);
printf("%lld",sum(n));;
return 0;
}
非常显然,递归调用的栈太多,直接爆栈,导致大数据跑不动。
代码2:
计算原理:sum(n)=sum(n-1)+sum(n-2)
#include<cstdio>
#include<iostream>
using namespace std;
typedef unsigned long long ull;;
#define digit 1000000
const int mod=100003;
ull record[digit];
ull sum(ull n)
{
if(record[n]) return record[n];
//重点语法,没了这句会慢很多
if(n==1) return record[n]=1;
if(n==2) return record[n]=2;
else return (record[n]=sum(n-1)+sum(n-2))%mod;
}
int main()
{
ull n;
scanf("%lld",&n);
printf("%lld",sum(n));;
return 0;
}
采用了记忆化搜索后,程序的快了许多,面对大数据也能跑过
总结
这就是记忆化搜索的模板,若想调用记忆化搜索来降低时间复杂度,都可以参考一下这个模板
递归的实质
每递归调用一次函数,系统就会生成一个新的函数实例。这些函数实例有同名的参数和局部变量,但各自独立,互不干扰。流程执行到哪一层,那一层的变量就起作用,返回上一层,就释放掉低层的同名变量
递归过程
- 参数:明确参数的意义以及当前的值;
- 边界:一个递归函数一定要有边界,而且边界一定要考虑全面,不能漏,否则它就可能死循环;
- 范围:就是在递归时的选择往哪儿走,也就是说,递归调用的函数返回值。
记忆化搜索的过程
- 定义好一个数组,用来存储递归所求出来的值
- 在主程序里,memset一下,一般都是赋初值为-1,然后把这个数组的边界值设置好
- 在递归函数里,首先加一句:if (这个数组的值>=0) return 这个值【如果赋初值为-1的话,一般都是>=0】
- 在后面的递归调用中,先给这个数组赋值,再return。