51Nod 1296 構造排列 DP

2021-08-21 10:39:29 字數 2616 閱讀 2883

題目鏈結

題意:給定n,要求構造滿足要求的排列,對於其中的一些成員,值大於左右鄰居,對於另一些成員,值小於左右鄰居。輸出滿足條件的排列種數。

思路:設dp[

i][j

]dp[i][j]

dp[i][

j]為前i

ii 個數構成的滿足條件的合法排列,且末尾為j

jj的個數。

那麼對於第i

ii個數,我們只需要考慮其與左鄰居的關係(第i個數與右鄰居的關係等價於第(i+1)個數與左鄰居的關係)

構建乙個陣列a

aa如果第i

ii個數大於左鄰居,則a[i

]=

1a[i] = 1

a[i]=1

如果第i

ii個數小於左鄰居,則a[i

]=

0a[i] = 0

a[i]=0

如果第i

ii個數等於左鄰居,則a[i

]=−1

a[i] = -1

a[i]=−

1 另外還需要考慮的乙個問題是,當我們在考慮前i

ii個數組成的排列且末尾為j

jj時,我們如何通過dp[

i−1]

dp[i-1]

dp[i−1

]的值來快速推出dp[

i]

dp[i]

dp[i

]的值,因為當j

<

ij < i

j<

i時,對於dp[

i−1]

dp[i-1]

dp[i−1

]陣列中的合法排列,j

jj是有可能已經出現在這些排列的中間,如果再在末尾插入j

jj,就出現了排列中有兩個j

jj的矛盾。

那應該如何來解決這個問題呢?此時有乙個非常巧妙也非常經典的構建新排列的方式,當我們在乙個排列的末尾插入j

jj時,為避免衝突,我們將原排列的所有不小於j

jj的數通通+1+1

+1,這樣的好處時,既不破壞原排列相鄰數之間的大小關係,同時也避免了兩個j

jj出現的可能。

故此時就可以利用排列的構造方法來求得dp的狀態轉移方程了:

當a [i

]=

1a[i] = 1

a[i]=1

時 d p[

i][j

]=∑k

=1j−

1dp[

i−1]

[k

]dp[i][j] = \sum_^dp[i-1][k]

dp[i][

j]=∑

k=1j

−1​d

p[i−

1][k

]當a[i]

=0

a[i] = 0

a[i]=0

時 d p[

i][j

]=∑k

=ji−

1dp[

i−1]

[k

]dp[i][j] = \sum_^dp[i-1][k]

dp[i][

j]=∑

k=ji

−1​d

p[i−

1][k

]當a[i]

=−

1a[i] = -1

a[i]=−

1時 dp[

i][j

]=∑k

=1i−

1dp[

i−1]

[k

]dp[i][j] = \sum_^dp[i-1][k]

dp[i][

j]=∑

k=1i

−1​d

p[i−

1][k

] 此題得解。

**:

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int mod =

1e9+7;

const

int a =

5000+10

;int dp[a]

,sum[2]

[a],a[a]

;int

main()

for(

int i=

1;i<=l ;i++

) a[x]=1

;a[x+1]

=0;}

if(flag ==0)

puts

("0");

else

} ll ans =0;

for(

int i=

1;i<=n ;i++)if

(ans <

0) ans +

= mod;

printf

("%i64d\n"

,ans);}

return0;

}

51Nod 1296 有限制的排列

acm模版 個人感覺,這個應該算是數字 dp。先通過處理輸入資料獲取乙個 state,表示每相鄰兩項之間的大小關係,state i 0,表示無特別關係,state i 1 表示第 i 項小於第 i 1 項,state i 2 表示第 i 項大於第 i 1 項。接著搞乙個 dp i j 表示由前 i ...

51Nod 1296 有限制的排列

計算整數集合滿足下列條件的的排列個數 在位置a1,a2,ak小於其鄰居 編號從0開始 在位置b1,b2,bl大於其鄰居。輸出符合條件的排列數量mod 1000000007的結果。例如 n 4,a b 符合條件的排列為 2 1 4 3 3 2 4 1 4 2 3 1 3 1 4 2 4 1 3 2 i...

51Nod 1020 逆序排列(DP)

題目鏈結 題目描述 在乙個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序數是4。1 n的全排列中,逆序數最小為0 正序 最大為n n 1 2 倒序 ...