動態規劃
設定狀態: f[i] 表示含i個元素的排列能生成的錯亂的數量
狀態轉移方程: f[i] = (i - 1) * (f[i-1] + f[i-2])
邊界: f[1] = 0, f[2] = 1
對於 f[n] 的計算, 假定把 n 放到了第 k 個位置:
- 這時如果把 k 放到了第 n 個位置, 那麼剩下的 n-2 個元素的錯亂即爲 f[n-2]
- 如果把 k 放到了其他位置, 也就是說 k 不能放到 n, 與 n-1 個元素的錯亂中 "k不能放到k" 是等價的, 也就是說, 這時是 f[n-1]
k一共有 n-1 個選擇, 故 f[n] = (i - 1) * (f[n-1] + f[n-2])
public class Solution { /** * @param n: an array consisting of n integers from 1 to n * @return: the number of derangement it can generate */ public int findDerangement(int n) { if (n <= 1) { return 0; } long[] dp = new long[n + 1]; int mod = 1000000007; dp[2] = 1; for (int i=3; i < n + 1; i++) { dp[i] = (long) (i - 1) * (dp[i-2] + dp[i-1]) % mod; } return (int)dp[n]; } }