傳球遊戲(遞歸水文)
所以說在被遞歸暴力的狠狠的虐了之後,我終於也可以虐遞歸啦(不存在的),於是懷著對漢諾塔的敬意和對遞歸的迷茫敲下了這篇總結,請記住:萬物皆虛,萬世皆允(劃掉)。
最初開始看遞歸的時候,我是被逼得想從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的博客去,你們不能指望我一個蒟蒻寫什麽高深的東西。
傳球遊戲(遞歸水文)