題目描述: 有 n 根高度各不相同的木棍(高度 1 到 n),排成一列。從左邊看,只有前方沒有更高木棍遮擋的才「可見」。求有多少種排列方式使得恰好有 k 根木棍可見(答案對 10⁹+7 取模)。
解題思路: 此問題與無符號第一類 Stirling 數(Unsigned Stirling Numbers of the First Kind)密切相關。
DP 定義:dp[i][j] = 將 i 根木棍排列使得恰好 j 根可見的方案數。
轉移:考慮最矮的木棍(高度 1)的位置:
dp[i-1][j-1](i-1) * dp[i-1][j]遞推式:dp[i][j] = dp[i-1][j-1] + (i-1) * dp[i-1][j]
基底:dp[0][0] = 1。
時間複雜度:O(n × k) — 雙重迴圈,外層 n 次,內層最多 k 次。
空間複雜度:O(k) — 使用一維滾動陣列。
1. Initialize dp[0..k] = 0, dp[0] = 1
2. For i from 1 to n:
a. For j from min(i, k) down to 1:
- dp[j] = (dp[j-1] + (i-1) * dp[j]) % MOD
b. dp[0] = 0
3. Return dp[k]二維 DP O(n × k) 空間:直接維護 dp[i][j] 二維表。邏輯更清晰但空間 O(nk)。
Stirling 數公式:此問題的答案就是無符號第一類 Stirling 數 S(n, k)。可以用生成函數或遞推關係計算,本質上就是上述 DP。理論上也可以用 FFT 加速多項式乘法到 O(n log² n),但實作複雜度高。