【LintCode】869. 找出一個數組的錯亂(動態規劃)

動態規劃

設定狀態: 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];
        
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章