# 題目: UVa 11420 - Chest of Drawers

# 題目說明

題目中的櫃子由數個抽屜堆疊而成,但是這種櫃子有安全上的疑慮
若你將一個抽屜完全抽出,那你能拿到下一層抽屜的東西
當前有L個抽屜,有S格是完全安全的,求總共有幾種排列法?

例如: L = 6, S = 4
則有6種可能

  1. U L L L L L
  2. L U L L L L
  3. L L U L L L
  4. L L L U L L
  5. L L L L U L
  6. L L L L U U
    (L為上鎖的,U為未上鎖的,粗體為不安全)

INPUT:
每筆測資輸入兩個整數LS,前者代表總抽屜數,後者代表安全的抽屜數
LS小於0時結束


OUTPUT:
輸出L個抽屜中有S個是安全的共有幾種排列法?

# 解題方法

先將所以可能的情況以動態規劃算出,再根據LS的值查表輸出


先定義一個dp[i][j][k]

  1. i為抽屜的數量
  2. j為有多少抽屜式安全的
  3. k分兩種情況,k = 0代表最上層的抽屜未上鎖,k = 1代表最上層抽屜上鎖

dp[1][0][0]dp[1][1][1]設為1

  1. 若只有1個抽屜時,0個抽屜是安全的,代表最上層為未上鎖的抽屜
  2. 若只有1個抽屜時,1個抽屜是安全的,代表最上層為上鎖的抽屜

j = 0,則k不可能為1,所以只有1種情況,需分開處理
dp[i][0][0] = dp[i - 1][1][1] + dp[i - 1][0][0]
當從i - 1個抽屜新增一個未上鎖的抽屜時

  1. k = 1只有最上層一個抽屜是安全時,新增一個未上鎖的抽屜會使原本安全的抽屜變不安全
  2. 若沒有抽屜是安全的,則新增一個未上鎖的抽屜不影響

以下為ij均不為0的情況

  1. dp[i][j][0],也就是k = 0時,代表在最上層新增一個未上鎖的抽屜
    • dp[i - 1][j + 1][1]此情況下在最上層新增一個未上鎖的抽屜,會導致原本安全的抽屜變不安全
    • dp[i - 1][j][0]不影響其他抽屜
  2. dp[i][j][1],也就是k = 1時,代表在最上層新增一個上鎖的抽屜
    • dp[i - 1][j - 1][1]直接新增一個安全的抽屜,不影響其他抽屜
    • dp[i - 1][j - 1][0]同上

# 參考程式碼

#include <iostream>

using namespace std;

long long dp[67][67][2];
int N, S;

int main()
{
	// fast io
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	// if there is one drawer, and no safe drawers, the top drawer must be unlock
	// if there is one drawer, and exist one safe drawer, the top drawer must be lock
	dp[1][0][0] = 1;
	dp[1][1][1] = 1;

	for (int i = 2; i < 66; ++i)
	{
		// if there is i drawers, and no safe drawers =
		// there is (i - 1) drawers, the top one is the only lock drawer +
		// there is (i - 1) drawers, no drawer is safe
		dp[i][0][0] = dp[i - 1][1][1] + dp[i - 1][0][0];

		for (int j = 1; j <= i; ++j)
		{
			// add one unlock drawer
			// if the top drawer is lock, this will lead to it unsafe
			dp[i][j][0] = dp[i - 1][j + 1][1] + dp[i - 1][j][0];

			// add one lock drawer
			dp[i][j][1] = dp[i - 1][j - 1][1] + dp[i - 1][j - 1][0];
		}
	}

	while (cin >> N >> S, N >= 0 && S >= 0) cout << dp[N][S][0] + dp[N][S][1] << "\n";

	return 0;
}

# 參考資料

https://www.larrysprognotes.com/UVa-11420/