【牛客】發郵件

題目傳送門:點我

        NowCoder每天要給很多人發郵件。有一天他發現發錯了郵件,把發給A的郵件發給了B,把發給B的郵件發給了A。於是他就思考,要給n個人發郵件,在每個人僅收到1封郵件的情況下,有多少種情況是所有人都收到了錯誤的郵件?
即沒有人收到屬於自己的郵件。

結合我們的做題步驟:

1).定義一個能夠清楚描述最優子問題的數組(明確數組描述的含義)。

2).找出數組元素之間的關係式(狀態轉移方程)

3).找出初始值

 

code:

這道題的狀態轉移方程還是不容易找出的(南首- - )。

 A  B C ... N (郵件)

  a  b  c ... n(郵箱)

假設A放入b

   1)如果 B放入a 那麼剩下n-1個的郵件或郵箱和abAB都沒有了關係記爲dp[i] = dp[i-2]

    2)如果B沒有放入a 那有如下狀態:

 B C ... N (郵件)

  a  c ... n(郵箱)

dp[i] = dp[i-1]

 

綜合1)2)並且,還有其他情況 A裝入c,裝入i的i-1種錯誤之下,同樣都有dp[i-1]+dp[i-2]種錯裝法,因此

dp[i] = (i-1) * (dp[i-1] + dp[i-2])

public class LTDP {


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) {
            int b = sc.nextInt();
            System.out.println(ErrNum(b));
        }
    }

    private static long ErrNum(int num) {
        long [] dp = new long[num + 1];  // dp[i]表示第i個郵件以及之前錯裝的種類數量
        dp[1] = 0; dp[2] = 1;
        if(num == 2 ){
            return dp[2];
        }
        for(int i = 3 ;i <= num;i++){
            dp[i] = (i - 1) *(dp[i-1] + dp[i-2]);// 轉移方程 :如何得出如上述解釋
        }
        return dp[num];
    }
}

 

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