王道機試 第十二章 動態規劃 12.1遞推求解
12.1 遞推求解
例題12.1 N階樓梯上樓問題(華中科技大學複試上機題)
- 動態規劃思路
(1)第一步
- 設變量,求什麼設什麼。
- 題目希望求出到達階臺階的方案書,則令表示到達第i階臺階的所有方案數。
(2)第二步
- 推導遞推方程。
- 考察數列每一項的關係。
- 由題意知,從第階臺階可到達第階臺階或者第階臺階。則第級臺階()的方案數,即。
(3)第三步
- 確定初始值
- 由於,且,故而我們需要求出數列的前兩項和,從而根據初始值和遞推方程,最終計算出。
- 顯然,, 。
C++代碼如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 105;
long long dp[maxn]; // 到達第k階臺階的方案數(求什麼設什麼)
int main()
{
memset(dp, 0, sizeof(dp));
dp[1] = 1; dp[2] = 2; // 初始化,計算n=1和n=2的情況
for (int i = 3; i < maxn; i++){
dp[i] = dp[i - 1] + dp[i - 2]; // 上到第i階臺階,其上一步的位置可能在i-1臺階(上一個臺階),或i-2臺階(上兩個臺階)
}
int n;
while (cin >> n){
cout << dp[n] << endl;
}
return 0;
}
習題12.1 喫糖果(北京大學複試上機題)
- 思路
- 和例題12.1 N階樓梯上樓問題變量、初始值、遞推方程完全一致。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 25;
int dp[maxn]; // 第k天喫完糖果的方案數
int main()
{
memset(dp, 0, sizeof(dp));
dp[1] = 1; dp[2] = 2; // 初始值
for (int i = 3; i < maxn; i++){ // 遞推方程
dp[i] = dp[i - 1] + dp[i - 2];
}
int n;
while (cin >> n){
cout << dp[n] << endl;
}
return 0;
}