所以说在被递归暴力的狠狠的虐了之后,我终于也可以虐递归啦(不存在的),于是怀着对汉诺塔的敬意和对递归的迷茫敲下了这篇总结,请记住:万物皆虚,万世皆允(划掉)。
最初开始看递归的时候,我是被逼得想从9楼信仰之跃的(虽然我那会还没开始玩刺客信条……),总之就是很懵,现在还好。
总之递归就是一种调用自身进行运算的骚操作,当然,我知道这么说你们也不懂,我们用数学函数一种类似的做法来表示以方便理解,f(f(f(f(f(x-2))))),那么从这个函数我们可以看出来,这是一种将大问题向下化为小问题,在通过小问题逆向推导出大问题的做法,以这个函数举例,要想求出最终解,首先要求出x-2,然后一层一层进行运算,当然,递归与这种函数具有很大的差距。
递归的一般形式就不打了,来谈谈递归的运行,大量的内容在书上已经很是详尽了,所以我们用具体题目来理解递归:
那么这道题是一道不算难的题目,其主要思想在于分情况讨论,然后就是,纯递归会因为运行过慢爆掉,所以我们用空间换时间的思想,用记忆化搜索解决
代码如下:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
int n,m;
int ans=0;
int f[50][50];
int cq(int k,int x)//k次传,x个小学生
{
if(f[k][x]>=0) return f[k][x];
if(k==m)//边界,如果传球次数达到m,结束递归
{
if(x==1)
return 1;
return 0;
}
if(x==n) //特判,当传到第n个人手里时
{
f[k][x]=cq(k+1,n-1)+cq(k+1,1);
}
else
if(x==1) //特判,当传到第1个手里时
{
f[k][x]=cq(k+1,n)+cq(k+1,2);
}
else //正常传球方式
{
f[k][x]=cq(k+1,x+1)+cq(k+1,x-1);
}
return f[k][x];
}
int main()
{
cin>>n>>m;
memset(f,-1,sizeof(f));
f[m][1]=1;
cout<<cq(0,1);
return 0;
}
从这道题,我们就可以较为清楚了理解递归的基础思维,至于更深层次的?自己翻dalao的博客去,你们不能指望我一个蒟蒻写什么高深的东西。