王道機試 第十二章 動態規劃 12.1遞推求解

王道機試 第十二章 動態規劃 12.1遞推求解

12.1 遞推求解

例題12.1 N階樓梯上樓問題(華中科技大學複試上機題)
  • 動態規劃思路

(1)第一步

  • 設變量,求什麼設什麼
  • 題目希望求出到達NN階臺階的方案書,則令dp[i]dp[i]表示到達第i階臺階的所有方案數。

(2)第二步

  • 推導遞推方程
  • 考察數列an(n1){a}_n(n \geq 1)每一項的關係。
  • 由題意知,從第ii階臺階可到達第i+1i+1階臺階或者第i+2i+2階臺階。則第nn級臺階(n3n \geq 3)的方案數an=an1+an2a_n = a_{n - 1} + a_{n - 2},即dp[i]=dp[i1]+dp[i2]dp[i] = dp[i - 1] + dp[i - 2]

(3)第三步

  • 確定初始值
  • 由於an=an1+an2a_n = a_{n - 1} + a_{n - 2},且n3n \geq 3,故而我們需要求出數列的前兩項a1a_1a2a_2,從而根據初始值和遞推方程,最終計算出ana_n
  • 顯然,a1=1a_1 = 1, a2=2a_2 = 2

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章