数组解简单多次递归
来源:互联网 发布:中博软件学院 编辑:程序博客网 时间:2024/06/02 05:31
OJ题:超级台阶
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第m级,共有多少走法?
注:规定从一级到一级有0种走法。
输入
输入数据首先包含一个整数n(1<=n<=100),表示测试实例的个数,然后是n行数据,每行包含一个整数m,(1<=m<=40), 表示楼梯的级数。
输出
对于每个测试实例,请输出不同走法的数量。
一开始是用一个递推公式来求n阶台阶的走法
f(n) = f(n-1) +f(n-2)
从第4阶台阶开始,到达第n阶台阶总共有两种方法,一是从n-1阶台阶一次走一步,一是从n-2阶台阶一次走两步,而从n-2阶台阶先走一步再走一步到达的这种情况,实际上是从n-2阶台阶先走一步到达n-1阶再走一步,是属于第一种情况的
以此便可以得出上述递推式。
而n为1、2、3的情况直接求出便可。
这样便得出求走n阶台阶的方法的函数
#include <iostream>using namespace std;int f(int m){ if(i==1) return 0; if(i==2) return 1; if(i==3) return 2; return f(m-1)+f(m-2);}int main(){ int s;cin>>s; while(s--) { int m;cin>>m; cout<<f(m)<<endl; } return 0;}
而在主函数调用时发现超时
仔细研究,觉得这个递推公式应该已经是最简单的了
虽然知道递归那里时间复杂度很高,但是发现每次调用f()函数都要进行3次判断。
刚好发现了前面的操作可以合成为一个,于是把f()函数改成
int f(int m){ if(m<=3) return m-1; return f(m-1)+f(m-2);}
这样时间复杂度前面的系数可以变成1/3。
但是果然还是太天真了,还是递归了太多层才超的时
突然看到输入限制中,1<=m<=40
突然想到可以做一个数组,直接把每一个值的结果求出来,而因为前面的值已经求出来了,求当前第n阶的方法时,就只需要执行一次加法操作
a[n]=a[n-1]+a[n-2];
果然
修改代码后AC了。
#include <iostream>using namespace std;int main(){ int s;cin>>s; int a[41]; a[1]=0;a[2]=1;a[3]=2; for(int j=4;j<=40;j++) a[j]=a[j-1]+a[j-2]; while(s--) { int m;cin>>m; cout<<a[m]<<endl; } }
然后突然想到前两天刚开始做OJ做了一道题,一直超时,好像也可以这样求出来,于是立马回到那题
OJ题目:孪生素数问题
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
写一个程序,找出给出素数范围内的所有孪生素数的组数。一般来说,孪生素数就是指两个素数距离为2,近的不能再近的相邻素数。有些童鞋一看到题就开始写程序,不仔细看题,咱们为了遏制一下读题不认真仔细的童鞋,规定,两个素数相邻为1的也成为孪生素数。
输入
第一行给出N表示测试数据组数。(1<=N<100)
接下来组测试数据给出m,表示找出m之前的所有孪生素数。
(1<=m<1000000)
输出
每组测试数据输出占一行,该行为m范围内所有孪生素数组数
这个问题,一开始是从3开始,遍历所有不大于m的奇数,先判断这个奇数是不是质数,如果是再判断相邻的奇数是不是质数。
判断素数需要√n的时间复杂度,总共有n/2个数要判断。
虽然不能直接相乘,但是应该和√n*n的规模差不多
而m取到最大值的时候,显然就超时
当时做这题筛选法求质数也没做出来,反而一经上题启发
直接就开始写
#include <iostream>using namespace std;int a[1000001];bool prime(int n){ if(n<=1) return false; for(int i=2;i*i<=n;i++) if(n%i==0) return false; return true;}int pri(int n){ if(prime(n)&&prime(n-2)) return 1; else return 0;}int main(){ a[1]=0;a[2]=0;a[3]=1; for(int i=4;i<1000001;i++) { a[i]=a[i-1]+pri(i); } int s;cin>>s; while(s--) { int n;cin>>n; cout<<a[n]<<endl; } return 0;}
基本操作就变成了
a[i]=a[i-1]+pri(i);
两道题共同的地方就是,规模已知,然后第n次结果与前面的结果有关联,但是如果用递归或者蛮力,会很复杂,并且每次求一个不同的n,都要重新算。那么这样的话,建立一个等规模的数组,直接用前面的值按照公式去推后面的值,应该会要好一些。
- 数组解简单多次递归
- 简单的数组递归算法
- 递归在数组中的简单应用
- 复制多次数组 Java
- 复习用递归求fib函数,感觉还是数组简单
- 一个简单的递归实现数组组元素的组合
- C递归解简单汉诺塔
- 数组递归
- 数组,递归
- 递归函数调用多次导致栈溢出
- 简单递归
- 简单递归
- 简单递归
- 简单递归
- 简单递归
- 简单递归
- 简单递归
- 对同一个数组进行多次初始化
- Tree Cutting POJ
- 零基础学习JAVA编程题—温度转换
- WC2017 && THUWC2017 游记
- 关于“任何软件工程遇到的问题都可以通过增加一个中间层来解决”的明悟
- Android 注解的使用 xUtils3和ButterKnife控件的注解注入对比
- 数组解简单多次递归
- 在LINUX下探测硬件信息的命令
- Rails控制台出现current transaction is aborted错误的解决
- [BZOJ1086][SCOI2005]王室联邦(树上分块)
- 生产者与消费者问题研究
- 深入浅出搜索架构引擎、方案与细节(上)
- 浅谈C++指针
- PHP学习杂记(一)
- 记忆化搜索(字符串)——Kickstart 2017(Google Code Jam) A Round #B