階乘
費氏數列
long long factorial(long long n){
if(n==1)
return 1;
return n*factorial(n-1);
}long long Fibonacci(long long n){
if(n==1||n==2)
return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}最大公因數
int gcd(int a, int b){
if(b==0)
return a;
return gcd(b,a%b);
}14
36
2
28
8
8
1
6
6
1
2
6
3
0
a
b
a%b
想像你是電腦,正在計算費式數列的第n項......
f(6)
f(4)
f(5)
f(2)
f(3)
f(4)
f(3)
f(2)
f(1)
f(1)
f(2)
f(2)
f(3)
f(1)
f(2)
好多東西都重複算喔......可不可以記下結果?
可以喔~我們可以把計算過的先放在陣列中記起來,這就是簡單的DP
long long a[100000];
long long Fibonacci(long long n){
a[1]=1,a[2]=1;
for(int i=2;i<=n;i++){
a[i]=a[i-1]+a[i-2];
}
return a[n];
}| 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 |
|---|
想法:
void hanoi(int from, int to, int temp, int n)
{
if(n==1){
cout<<"Ring "<<n<<" from "<<from<<" to "<<to<<'\n';
return;
}
hanoi(from,temp,to,n-1);
cout<<"Ring "<<n<<" from "<<from<<" to "<<to<<'\n';
hanoi(temp,to,from,n-1);
}請輸出n個圓盤從第一根柱子移動到第三根柱子的最少步驟,並且輸出總共幾步。
找找看n和步數之間的關係~
你有一個限制重量W的背包,眼前有n個價值分別為vi、重量為wi的物品,請問你最高可以帶走多少價值的東西?
(假如W=9,跟旁邊的同學討論一下吧~)
W
| w (重量) | v (價值) | |
|---|---|---|
| 貓頭鷹玩偶 | 5 | 30 |
| 天使吊飾 | 3 | 25 |
| 遙控車 | 6 | 45 |
| 撲克牌 | 2 | 20 |
在找尋過程中,每個物品有「拿」和「不拿」兩種選項,因此如果有n個物品,則有 種可能
Yes
No
要不要拿
第1個物品?
參數:(拿到第幾個物品, 目前重量, 目前價值)
終止條件: 看完所有物品 || 重量超過背包限制
要不要拿
第2個物品?
Yes
No
Yes
No
要不要拿
第3個物品?
Yes
Yes
Yes
Yes
No
No
No
No
好慢,有沒有什麼可以改良的地方呢?
rec(i,w)定義成可以拿第0到i號的物品,回傳背包w可以裝得下的最大價值
rec(n-1, W)就是答案
rec(i, w)
可拿0~i號,限重w
不拿第i號
拿第i號
rec(i-1, w)
rec(i-1, w-wi)+vi
忽略第i個物品
可裝重量-wi,
答案價值+vi
| 編號 (i) | 0 | 1 | 2 |
|---|---|---|---|
| 重量 (w) | 1kg | 1kg | 2kg |
| 價值 (v) | $2 | $1 | $2 |
假設W=3,則遞迴樹如下
rec(i,w)定義成可以拿第0到i號的物品,回傳背包w可以裝得下的最大價值
rec(2,3)
rec(1,1)+2
rec(1,3)
rec(0,0)+1
rec(0,1)
rec(0,3)
rec(0,2)+1
rec(0,0)+1
放不了0號
rec(-1,0)
rec(-1,0)+2
rec(-1,1)
rec(-1,1)+2
rec(-1,2)
rec(-1,2)+2
rec(-1,3)
int w[MAXN], v[MAXN];
int dp[MAXN][MAXM+1] = {0};
int rec(int i, int W) {
if (i == -1)
return 0;
if (dp[i][W] > 0)
return dp[i][W];
if ( W-w[i] >= 0 ) {
dp[i][W] = max(rec(i-1, W), rec(i-1, W - w[i]) + v[i]);
}
else {
dp[i][W] = rec(i-1, W);
}
return dp[i][W];
}DP加上背包問題
| 類型 | 大概意思 |
|---|---|
| 0/1 背包問題 | 每個物品只有放和不放兩種選擇 |
| 完全背包問題 | 每個物品可以拿很多個 |
| 有限背包問題 | 物品有數量上的限制 |
詳解:演算法筆記
皇后攻擊範圍是他所在的行和列以及斜線。請問n*n的方格最多可以放下幾個皇后?(0<n<12)
int nq(int n){
int p[14], total=0;
for(int i=0;i<n;i++){
p[i]=i;
}
do{
bool valid=true;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(abs(p[j]-p[i])==j-i){
valid=false;
break;
}
}
}
if(valid){
total++;
}
}while(next_permutation(p,p+n));
return total;
}請跟旁邊的好同學一起互相討論,達成任務!
1
1
1
1
2
1
1
3
3
1
1
1
1
1
4
4
6
5
5
10
10
輸入:n 和 m
輸出:第n列,第m個數是什麼?
下面是卡特蘭數的遞迴型定義
輸入:n
輸出:第n項是多少?