遞迴
遞迴是什麼?
- 一種函式
 - 自己呼叫自己
 
聽起來很抽象?
舉例
階乘
\(n! = 1 * 2 * 3 ... * (n - 1) * n\)
定義函式\(f(n)\)為n!的值
舉例
\(n! = n * (n - 1)!\)
用遞迴表示\(f(n)\)
\(f(n) = f(n - 1) * n\)
\(f(3) = f(2) * 3\)
\(f(2) = f(1) * 2\)
\(f(1) = f(0) * 1\)
\(f(0) = f(-1) * 0\)
......\(\infty\)
寫出來看看
什麼時候結束?
遞迴終止條件
設結束條件
定f(1) = 1
\(f(3) = f(2) * 3\) = 6
\(f(2) = f(1) * 2\) = 2
\(f(1) = 1\)
#include<bits/stdc++.h>
using namespace std;
int f(int n){
	if(n == 1)
    	return 1;
	return f(n - 1);
}
int main(){
	int n;
    cin >> n;
    cout << f(n) << '\n';
}試試看吧
e156
費氏數列
- 1, 1, 2, 3, 5, 8, 13, 21, 34...
 - 第n項是前兩項和
 - \(f(1) = 1, f(2) = 1\)
 - \(f(n) = f(n - 1) + f(n - 2)\)
 
範例測資
輸入:5 輸出:5
輸入:9 輸出:34
#include<iostream>
using namespace std;
int f(int n) {
	if (n == 1)
		return 1;
	if (n == 2)
		return 1;
	return f(n - 1) + f(n - 2);
}
int main() {
	int x;
	cin >> x;
	cout << f(x) << '\n';
}河內塔
有a, b, c三根桿子,一開始有N個盤子由大到小往上疊,問最少要花多少步才能把所有盤子從a桿子移到c桿子。
#include<iostream>
using namespace std;
int f(int n) {
	if (n == 1)
		return 1;
	return f(n - 1) * 2 + 1;
}
int main() {
	int x;
	cin >> x;
	cout << f(x) << '\n';
}實際應用
1~n的所有排列
a524
快速冪
歐基里德算法
aka 輾轉相除法
遞迴枚舉
給一個有長度為n的整數陣列a,計算其中有多少種子集的和等於k。
遞迴枚舉
可以把每一個數字分為拿和不拿,透過遞迴跑過每個可能的狀況。
#include<iostream>
using namespace std;
int n, k, ans = 0, a[30];
void f(int i, int sum = 0) {
	if (i == n) {
		if (sum == k)
			ans++;
		return;
	}
	f(i + 1, sum + a[i]);
	f(i + 1, sum);
}
int main() {
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	f(0);
	cout << ans << '\n';
}遞迴
By scottchou
遞迴
- 246