题解 loj2719 「NOI2018」冒泡排序

考虑一个排列的交换次数何时会超过下界。以题目中的\(3\ 2\ 1\)为例,在把\(3\)向后移时\(2\)被向前推了一次,在把\(1\)向前移时\(2\)又被向后推了一次。这样一来一回,就产生了无效操作。于是我们发现,一个排列是好的,当且仅当在冒泡排序的过程中,不存在某个元素同时做了两个方向的移动(这样必然产生“一来一回”的情况)。

尝试把这个观察具体化一些。考虑一个位置\(i\),如果它前面存在一个\(>p_i\)的数,后面存在一个\(<p_i\)的数。则在冒泡排序的过程中,\(p_i\)必定是先被向后挪了一次,又被向前挪了一次(当然,也可能是先向前再向后)。也就是说,在这种情况下,\(p_i\)一定是同时做出了两个方向的移动。根据前面的讨论,此时这个排列\(p\)冒泡排序的交换次数,必然超过了下界\(\frac{1}{2}\sum|i-p_i|\)。打表可以验证,除了这种情况以外,其他的排列都能取到这个下界。于是我们得出结论:一个排列是“好”的,当且仅当它不存在一个长度\(\geq3\)的下降子序列,或者说最长下降子序列的长度\(<3\)

继续分析这个结论的特殊性质。考虑现在我们逐位构造一个“好”的排列,现在填到位置\(i\),前\(i-1\)位的最大值为\(mx\)。则第\(i\)位要么填任意一个\(>mx\)的数,要么填\(<mx\)的最小的数(否则就一定会出现长度为\(3\)的下降子序列)。于是想到DP。设\(dp[i][j]\)表示考虑了前\(i\)位,最大值是\(j\)时,第\(i+1\)到第\(n\)位的填数方案。这样我们可以从后往前转移,即得到:
\[ dp[i][j]=\left(\sum_{k=j+1}^{n}dp[i+1][k]\right)+dp[i+1][j]=\sum_{k=j}^{n}dp[i+1][k] \]
为什么要把DP数组定义成“第\(i\)位之后的填数方案”呢?因为这样便于我们处理字典序的问题。我们统计答案时,枚举从第\(i\)位开始,字典序第一次大于输入的排列\(q\)(前\(i-1\)位全部和\(q\)相等)。我们设\(mx_i=\max_{j=1}^{i}q_j\),则:
\[ ans_i=\sum_{j=mx_i+1}^{n}dp[i][j]=dp[i-1][mx_i+1] \]
答案就是所有\(ans_i\)之和。

这样暴力DP是\(O(n^3)\)的,用后缀和优化可做到\(O(n^2)\)

\(dp[i][j]\)视作从二维平面直角坐标系上一个点\((i,j)\)走到\((n,n)\)的方案数。每步必须向右走一格,同时可以向上走若干格或不向上走。但走的过程中,必须始终保证\(i\leq j\)。考虑用总方案减去不合法的(\(i>j\))的方案。

  • 总方案数相当于求\(n-i\)个非负整数使得它们和为\(n-j\)。根据经典的插板法,可知方案数为\({n-i+n-j-1\choose n-i-1}={2n-i-j-1\choose n-i-1}\)
  • 求路线中存在\(i>j\)的方案数。首先,所有这样的路线一定经过了直线\(y=x-1\)。根据卡特兰数的套路,对于所有不合法的路线,在它们第一次经过直线\(y=x-1\)时,将它们关于直线\(y=x-1\)对称。于是,每条不合法路线唯一对应一条从\((j+1,i-1)\)出发,走向\((n,n)\)的路线(注:其中\((j+1,i-1)\)\((i,j)\)关于\(y=x-1\)的对称点)。因此,不合法路线的数量就是从\((j+1,i-1)\)出发走向\((n,n)\)的路线数,即\({n-(j+1)+n-(i-1)-1\choose n-(j+1)-1}={2n-i-j-1\choose n-j-2}\)

综上,可知\(dp[i][j]={2n-i-j-1\choose n-i-1}-{2n-i-j-1\choose n-j-2}\)

按之前的方法,直接统计答案即可。

注意,如果\(q\)的前\(i\)位已经存在不合法的情况(不符合“第\(i\)位要么填一个\(>mx_{i-1}\)的数,要么填\(<mx_{i-1}\)的最小的数”这条规则),要及时break

时间复杂度\(O(n)\)

参考代码

猜你喜欢

转载自www.cnblogs.com/dysyn1314/p/12394402.html