基礎演算法 第1章 遞推演算法課堂過關

2022-07-10 19:57:14 字數 3783 閱讀 9341

目錄b. 【例題2】奇怪漢諾塔

c. 【例題3】數的劃分

d. 【例題4】傳球遊戲

e. 【例題5】平鋪方案

「基礎演算法」第1章 遞推演算法課堂過關

求多少個n個數的排列a,滿足對於任意的\(i (1\leq i \leq n) a_i \neq i\),輸入n,輸出乙個整數,表示答案

設\(f(n)\)表示n個數的合法方案排列個數

考慮第x個元素,把他放到k位置上,一共有 n-1種放法

考慮第k個元素,共兩種可能:

把k放在位置n,則對於除k,n以外的其他元素,錯排即可,共\(f(n-2)\)種方案

不把k放在位置n,則對於n-1個元素的錯排,有\(f(n-1)\)種方法

故,有遞推式:

\[f(x)=

\left\

(n-1)\cdot (f(x - 1) + f(x - 2)) \quad\ \ (x\geq3)\\

1\qquad\qquad\qquad\qquad\qquad\qquad\qquad(x=1)\\

2\qquad\qquad\qquad\qquad\qquad\qquad\qquad(x=2)

\end\right.

\]

#include #include #define int long long

using namespace std;

int n;

int ans;

int f(int x)

signed main() /*0

131256

3212175

17008

150504

1485465

*/

有a、b、c、d四座塔, 給定n個圓盤,一開始全部放在a塔,直接輸出n=1~12時的所有答案,無輸入

具體規則同普通漢諾塔

回顧三座塔的情況:

將a塔的n-1個圓盤移至b塔,最後乙個圓盤直接移至c塔,再將b塔的所有圓盤移到c塔

有遞推式:

\[d(x)=

\left\

&1+2\cdot d(x - 1) \qquad(x\geq2)\\

&1\qquad\qquad\qquad\qquad(x=1)

\end\right.

\]當漢若塔數量為4座時:

考慮將a塔的j個盤子轉移到b塔(移動步數為\(f(j)\)),然後不對b塔進行操作,將剩下n-j個盤子轉移到d塔,移動步數為\(d(n-j)\),最後將b塔的j個盤子轉移到d塔,移動步數為\(f(j)\),我們直接列舉j,取最小值即可

遞推式:

\[f(x)=

\left\

&\min \} \qquad(x\geq2,j\in[0,x])\\

&1\qquad\qquad\qquad\qquad\qquad\qquad\ (x=1)

\end\right.

\]

#include #include #define min_(_ , __) (_ < __ ? _ : __)

using namespace std;

int d[20] , f[20];

int main()

for(int i = 1 ; i <= 12 ; i++)

cout << f[i] << endl;

return 0;

}/*答案13

591317

2533

4149

6581

*/

將整數n分成k份,每份不為空,求不同的劃分方案數(數字相同而順序不同的兩個方案視為相同的方案)

例如:下面三種分法被認為是相同的:

1,1,5; 1,5,1; 1,1,5.
設$ f(n,k)$表示將整數n分成k份的不重複方案數

當\(n>k\)時:

k份中至少有乙份為「1」:方案數為\(f(n-1,k-1)\)

k份中沒有乙份為「1」 :方案數為\(f(n-k,k)\)(在n-k被分成k份的基礎上,每乙份都加上「1」)

故有遞推式:

\[f(n,k)=

\left\

&f(n-1,k-1)+f(i-k,k) \qquad\ \ \ (x>k)\\

&1\qquad\qquad\qquad\qquad\qquad\qquad\qquad(n=k)\\

&0\qquad\qquad\qquad\qquad\qquad\qquad\qquad(n

#include #include using namespace std;

int n , k;

int f[1010][1010];

int main()

cout << f[n][k];

return 0;

}

傳送門

設\(f(i , j)\) 表示經過j次傳球後,球落在第i個同學手中的方案數(說明一下,我**裡面把遊戲剛開始,球在小蠻手上的情況當做第1次傳球,故有一丟丟不一樣)

很顯然,有:

\[f(i,j)=f(i-1,j-1)+f(i+1,j-1)

\]其中,根據題目「n 個同學站成乙個圓圈」的背景,「i+1」 、"i-1"均應該在\([1,n]\)範圍內,越界自行處理

想出並寫出演算法10min,寫出高精度40min

設\(f(x)\)表示鋪成2*x的矩形的方案數

顯然\(f(1)=1,f(2)=3\)

對於其他情況,我們考慮:

將1*2的矩形豎著拼到2*(n-1)的矩形上,方案數為f(x-1)

將兩個1*2的矩形橫著拼到2*(n-2)的矩形上,方案數為f(x-2)

將乙個2*2的矩形橫著拼到2*(n-2)的矩形上,方案數為f(x-2)

故遞推式:

\[f(x)=

\left\

&2\cdot f(x - 2) + f(x - 1) \quad(x\geq3)\\

&1\qquad\qquad\qquad\qquad\qquad(x=1)\\

&3\qquad\qquad\qquad\qquad\qquad(x=2)

\end\right.

\]最後,看樣例都知道要高精度

#include #include #include #define ll long long

using namespace std;

#define m 1010

struct bignum

void print()

bignum operator + (const bignum &b) const

++ans.siz;

if(ans.a[ans.siz - 1] == 0)--ans.siz;

return ans;

}};bignum f[1010];

int main()

return 0;

}

Num 1 遞推演算法

getchar getchar 沒有引數,返回來自輸入裝置的下乙個字元。停住介面觀察結果 return 0 a上4年大學,假設銀行的年利率為0.018,a每月從銀行卡中取出1000元作為生活費,那麼求解最開始存入銀行卡的錢為多少?求解過程 若在第48個月a畢業時來本帶息取出100元,則要先求出第47...

第二章 遞推演算法

乙個問題的求解需一系列的計算,在已知條件和所求問題之間總存在著某種相互聯絡的關係,在計算時,如果可以找到前後過程之間的數量關係 即遞推式 那麼,從問題出發逐步推到已知條件,此種方法叫逆推。無論順推還是逆推,其關鍵是要找到遞推式。這種處理問題的方法能使複雜運算化為若干步重複的簡單運算,充分發揮出計算機...

第一章 遞推演算法

特點 乙個問題的求解需一系列的計算,在已知條件和所求問題之間總存在著某種相互聯絡的關係,如果可以找到前後過程之間的數量關係 即遞推式 那麼,從問題出發逐步推到已知條件,此種方法叫逆推。無論順推還是逆推,其關鍵是要找到遞推式。猴子吃桃 遞推關係 f n f n 1 2 1 f n 1 f n 1 2 ...