NOI2018 氣泡排序

2022-02-04 17:18:06 字數 2749 閱讀 8813

[noi2018]氣泡排序

題解性質+模型轉化

首先,乙個排列是「好」的,當且僅當:每個數,要麼是字首最大值,要麼是字尾最小值。(討論i和pi的關係即可證明)

也就是,排列不能存在》=3的下降子串行!

換句話說,假設之前填了i個數,最大值是mx,那麼第i+1個數,要麼是剩下數的最小值,要麼是比mx大的數。

字典序,肯定按位考慮,轉化成沒有限制的情況,

所以先處理沒有限制的情況

這樣dp,

$f[i][j]$剩下i個數,比之前最大值大的數有j個的方案數。

第n-i+1個位置,要麼填最小值,要麼填這j個數之一。

填這j個中第k大的數(它就成為了新的最大值),就只能剩下j-k個比最大值大的了。

轉移:$f[i][j]=\sum_^f[i-1][k]$,k=0代表填了最小值。字首和優化

當然,i>=j必須保證

然後可以卡位。

之前比最大值大的數有nw個,第i個位置數是ai,

第i個位置:

1.$p_i>a_i$

$p_i$一定是乙個比最大值大的數

如果$a_i$是字首最大值,則nw=n-a[i]

否則,nw=n-字首最大值

顯然為了嚴格大於,如果nw=0,一定不行。

自由之後,方案數是:$\sum_^f[n-i][j]=f[n-i+1][nw-1]$

2.$p_i=a_i$

判斷$a_i$是不是字首最大值或者字尾最小值即可

o(t*n^2)

過不去。

瓶頸在於o(n^2)dp

這個dp很模式化啊,,,

$f[i][j]=\sum_^f[i-1][k]$

能不能發現組合意義?

結論:$f[i][j]=c(i+j-1,j)-c(i+j-1,j-2)$

證明:顯然必須有i>=j

本質是,(0,0)往(i,j)走,每次要麼往右走,要麼往右上走,不越過直線(i=j)的方案數。

可以對偶成:從(1,1)走,每次往右往上走,不能越過直線(i=j-1)的方案數

藍色折線和綠色折線一一對應!

不合法的也一一對應!(請自行畫圖)

從(1,1)走,每次往右往上走,不能越過直線(i=j-1)的方案數

這個直接卡特蘭數一樣,對稱容斥下即可。

o(n)

//

luogu-judger-enable-o2

#include#define reg register int

#define il inline

#define fi first

#define se second

#define mk(a,b) make_pair(a,b)

#define numb (ch^'0')

#define pb push_back

#define solid const auto &

#define enter cout

namespace

std;

typedef

long

long

ll;template

il void rd(t &x)

template

il void output(t x)

template

il void ot(t x)

template

il void prt(t a,int st,int nd)

namespace

modulo

il int sub(int x,int y)

il int mul(int x,int y)

il void inc(int &x,int y)

il void inc2(int &x,int y)

il int qm(int x,int y=mod-2)return

ret;}

template

il int ad(const

int a,const

int b,const args &...args)

template

il int mul(const

int a,const

int b,const args &...args)

}using

namespace

modulo;

namespace

miracle

int f(int n,int

m)int

a[n];

bool

is[n];

intmain()

}int ans=0

;

int nw=n,mx=0

;

for(reg i=1;i<=n;++i)

if(a[i]>mx)

else

if(!is

[i])

}printf(

"%d\n

",ans);

}return0;

}}signed main()

/*author: *miracle*

*/

發現本質:乙個數要麼是字首最大值,要麼是字尾最小值

無限制?可以dp,f[i][j]記錄剩下的數以及比最大值大的數

字典序?按位考慮。變成無限制。

o(n^2)?觀察dp式子找到組合意義!

NOI2018 氣泡排序

題面 吐槽 好像發的pdf題面的冒泡是掛掛的,還好我還會氣泡排序 逃 具體思路 首先發現當這個序列的最長下降序列長度大於2時,一定不符合要求 那麼我們可以想出乙個 o n 2 的dp f i,j 表示前 i 個數,設其中最大的數為 mx 後面的數中有 j 個數比 mx 小的方案數 然後發現 f i,...

NOI2018 歸程 題解

容易發現,當水位線確定了,圖會被分成若干個連通塊,連通塊裡的點可以互相到達,故連通塊內點的答案為其中的點到 1 的距離的最小值,這個可以先 dijkstra 預處理求出 spfa 死了 那考慮怎麼維護連通塊。可持久化並查集?感覺不好搞,有一種神奇的演算法 kruscal 重構樹。其實就是 krusc...

NOI2018 你的名字

題目描述 小 a 被選為了 ion2018 的出題人,他精心準備了一道質量十分高的題目,且已經把除了題目命名以外的工作都做好了。由於 ion 已經舉辦了很多屆,所以在題目命名上也是有規定的,ion 命題手冊規定 每年由命題委員會規定乙個小寫字母字串,我們稱之為那一年的命名串,要求每道 題的名字必須是...