[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_{k=0}^{j}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_{j=0}^{nw-1}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_{k=0}^{j}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)
标签:前缀,要么,最大值,冒泡排序,往右,最小值,NOI2018,nw 来源: https://www.cnblogs.com/Miracevin/p/11032215.html