遞迴
一個函式重複呼叫自己,就是遞迴
一個函式重複呼叫自己,就是遞迴
#include<bits/stdc++.h>
using namespace std;
void g(int a){
if(a==0) return;
cout<<"haha"<<endl;
return g(a-1);
}
int main(){
g(4);
}有什麼用?
有什麼用?
枚舉、DFS、線段樹、分治................
有什麼用?
枚舉、DFS、線段樹、分治................
幾乎什麼都會用到
例題 : 費氏數列
是什麼應該不用我多說
1 1 2 3 5 8 13 21 34
是什麼應該不用我多說
0 1 1 2 3 5 8 13 21 34
f(i) = 費事數列第i項
f(i) = f(i-1) + f(i-2)
試著用遞迴做出求費事數列第 n 項
試著用遞迴做出求費事數列第 n 項
f(i) = f(i-1) + f(i-2)
f(1) = 0
f(2) = 1
#include<bits/stdc++.h>
using namespace std;
int f(int x){
if(x == 1) return 0;
if(x == 2) return 1;
return f(x-1)+f(x-2);
}
int main(){
int n; cin>>n;
cout<<f(n)<<endl;
}如果我要求第45項 ...
如果我要求第45項 ...
居然卡住了
如果我要求第45項 ...
居然卡住了
n
n-1
n-2
n-4
n-3
n-3
n-2
.......
1 or 2
如果我要求第45項 ...
居然卡住了
n
n-1
n-2
n-4
n-3
n-3
n-2
.......
1 or 2
好多重複的東西 !
把重複的東西記起來
n
n-1
n-2
n-4
n-3
n-3
n-2
n-3
n-4
把重複的東西記起來
n
n-1
n-2
n-4
n-3
n-3
n-2
n-3
n-4
#include<bits/stdc++.h>
using namespace std;
#define int long long
int tmp[10000000];
int f(int x){
if(x == 1) return 0;
if(x == 2) return 1;
if(tmp[x] != 0) return tmp[x];
return tmp[x] = f(x-1)+f(x-2);
}
main(){
cout<<f(70)<<endl;
}例題 : 河內塔
規則 :

給定一開始A上的盤子數
求最少步驟數
求步驟(幾號盤子從哪裡搬到哪)
遞迴 -> 拆解問題
怎麼拆?
遞迴 -> 拆解問題
怎麼拆?
先幫盤子由上往下編號1~n
假設現在有 n 個盤子在 A
怎麼移 ?
假設現在有 n 個盤子在 A
怎麼移 ?
我可以先把 1~n-1 共n-1個盤子移到B
假設現在有 n 個盤子在 A
怎麼移 ?
我可以先把 1~n-1 共n-1個盤子移到B
再把n號盤從A移到C
假設現在有 n 個盤子在 A
怎麼移 ?
我可以先把 1~n-1 共n-1個盤子移到B
再把n號盤從A移到C
最後把1~n-1號盤從 B 移到 C
因此假設 f(x) 是 n = x 的答案
f(x) = f(x-1) + f(1) + f(x-1)
f(x) = f(x-1) +1+ f(x-1)
f(x) = f(x-1)*2+1
#include<bits/stdc++.h>
using namespace std;
#define int long long
int tmp[1000000];
int f(int x){
if(tmp[x] != 0) return tmp[x];
if(x == 1) return tmp[x] = 1;
return tmp[x] = 2*f(x-1) + 1;
}
main(){
int n; cin>>n;
cout<<f(n)<<endl;
}最少布數好了,那實際步驟呢 ?
最少布數好了,那實際步驟呢 ?
!!! 注意到
把 f(x) 拆成 f(x-1) 後,就變成 n = x-1問題的了
不用管n號盤
是兩件獨立的事情
最少布數好了,那實際步驟呢 ?
!!! 注意到
把 f(x) 拆成 f(x-1) 後,就變成 n = x-1問題的了
不用管n號盤
是兩件獨立的事情
設 f(x,A,C,B)
把 x 個盤子從 A 移到 C,藉由 B
設 f(x,A,C,B)
把 x 個盤子從 A 移到 C,藉由 B
這裡的ABC只是代號 !!
f(x,A,C,B) = f(x-1,A,B,C) + 把n號從A移到C + f(x-1,B,C,A)
把n號從A移到C、x = 1
是真正我要動的步驟
#include<bits/stdc++.h>
using namespace std;
#define int long long
void f(int x,char A,char C,char B){
if(x==1){
cout<<"Move ring 1 from "<<A<<" to "<<C<<endl;
return;
}
f(x-1,A,B,C);
cout<<"Move ring "<<x<<" from "<<A<<" to "<<C<<endl;
f(x-1,B,C,A);
}
main(){
int n; cin>>n;
f(n,'A','C','B');
}遞迴
By maxbrucelen
遞迴
- 176