BZOJ 3591 最長上公升子串行

2021-10-03 06:41:46 字數 1212 閱讀 3264

題目鏈結

題意:給定 k

kk 個數,求所有長度為 n

nn 且最長上公升子串行的排列為給定的 k

kk 個數的方案數。

n

<=15

n<=15

n<=1

5

首先想到可以用狀壓解決排列的順序問題,而僅通過 0,1

0,10,

1 無法表達出最長上公升子串行的長度,而再開一維進行表示也無法進行有效轉移。那麼考慮在求是 lis

lisli

s 時我們會對乙個陣列不斷進行覆蓋,每個數字會逐個填入或被覆蓋,那麼如果我們用0,1

,2

0,1,2

0,1,

2 三個狀態分別表示未用、已用、已被覆蓋,即可通過此得到最長上公升子串行的長度及其他序列資訊,並可以輕鬆轉移。而考慮到複雜度 o(n

3n

)o(n3^n)

o(n3n)

已經很大,在對每個三進製狀態進行列舉時,按從小到大的順序進行列舉,另乙個計算最長上公升子串行長度的指標滿足單調性,因此不會增加額外複雜度。

#include

using

namespace std;

const

int inf=

0x3f3f3f3f

;int dp[

15000000];

int is[20]

,pre[20]

,ppow[20]

,a[20

],lis[20]

;int

main()

ppow[1]

=is[0]

=1;for

(int i=

2;i<=n+

1;i++

) ppow[i]

=ppow[i-1]

*3;int res=0;

dp[0]

=1;for

(int i=

0;i<

(ppow[n+1]

);i++)if

(tot==n)

lis[cnt]

=inf;

int k=1;

for(

int j=

1;j<=n;j++)}

cout<}

BZOJ 3591 最長上公升子串行

哎我還是太菜了,這麼短的 斷斷續續 調了好久。看資料範圍 大概就是狀壓dp 題目名字是 最長上公升子串行 可以猜測是拿跑li s 的單調棧搞搞。那麼可以設計乙個狀態f a b 表示已選集合 a 其中 b是當前單調棧裡的元素,顯然棧裡的元素公升序排列,不用額外加一維狀態表示棧中元素的排列。顯然這可以優...

BZOJ3591 最長上公升子串行

考慮我們做最長上公升子的過程,維護乙個單調棧,每次加入乙個元素,替換掉最前面乙個比他大的數 我們可以dp這個加入元素的過程,用乙個3進製的狀態表示每個數在不在佇列裡且在不在棧裡,可以用o n22n o n 22n 預處理對於棧中的每個狀態,加入乙個新的數之後的狀態 然後做乙個o n3n o n 3n...

BZOJ3591 最長上公升子串行 狀壓DP

description 給出1 n的乙個排列的乙個最長上公升子串行,求原排列可能的種類數。sample input53 1 3 4 sample output 11挺好的dp題。我們先考慮普通lis,我們維護乙個序列,每一次盡量去替換序列中的值。對於這個,可以用乙個三進製維護,0表示未進佇列,1表示...