1. 程式人生 > >某次模擬賽 交換

某次模擬賽 交換

amp 組合 得到 需要 left lsp 根據 限制 範圍

題目描述 Description

給定一個{0, 1, 2, 3, … , n - 1}的排列 p。一個{0, 1, 2 , … , n - 2}的排列 q 被認為是優美的排列,當且僅當 q 滿足下列條件:
對排列 s = {0, 1, 2, 3, ..., n - 1}進行 n – 1 次交換。
1. 交換 s[q0],s[q0 + 1]
2. 交換 s[q1],s[q1 + 1]

最後能使得排列 s = p.
問有多少個優美的排列,答案對 10^9+7 取模。

輸入描述 Input Description

第一行一個正整數 n.
第二行 n 個整數代表排列 p.

輸出描述

Output Description

僅一行表示答案。

樣例輸入 Sample Input

3
1 2 0

樣例輸出 Sample Output

1

數據範圍及提示 Data Size & Hint

30%: n <= 10

100%: n <= 50

之前的一些廢話:《摔跤吧爸爸》這部電影真是太感動了

題解:還是覺得這種題挺難的,考試時候想不到正解的話花幾分鐘把30分拿了其實也挺爽的。

控制交換次數為n-1,所以我們可以這麽考慮:考慮倒著處理,比如交換 (i, i + 1),那麽前面的所有數不管怎麽交換都無法到後面去(下標恒小於等於 i),後面的數也是一樣到不了前面。說明這最後一次交換前,就要求對於所有的 x <= i, y > i,px<py。所以交換前左邊的數是連續的,右邊也是連續的。由於交換前,前面和後面的數是互相不幹涉的,所以就歸結成了兩個子問題。(這段話是搬運題解而來的)

想到這裏,就不太難了,很明顯的區間DP:dp[i][j]表示將當前序列的第i個數到第j個數換成最終序列的方案數,只要區間長度確定了,那麽交換次數也確定了,所以沒有必要再單開一個狀態來存交換次數。根據區間DP的套路,轉移肯定是枚舉中間點,但是還有一個限制:假如要在[L,R]中選取第k和第k+1個數進行交換,那麽交換之後[L,K]中的數是再也不可能換到K以後了的,[K+1,R]中的數也不可能換到K+1以前了,所以需要保證交換第k和第k+1個數後,新序列中[L,K]的數都小於等於K,而[K+1,R]的數都大於K。只有滿足以上限制的才能進行轉移。轉移方程是:dp[L,R]+=dp[L,K]*dp[K+1,R]*C(R-L,K-L-1),至於為什麽要乘上一個組合數...自己想一想吧。

然後需要一個組合數預處理。

代碼:目前暫時無法得到。。

總結:突破口在於控制交換次數,算是一種經驗吧。

某次模擬賽 交換