zoukankan      html  css  js  c++  java
  • NOI2018 冒泡排序

    这是 NOI 的一个非常非常好的组合计数题。

    题目

    先考虑这么一个问题: 有一个长度为 (n) 的排列,它的前 (m) 位给定,问有多少种确定剩下 ((n-m)) 位的方案使得整个排列是好的。

    结论:一个长度为 (n) 的排列是「好」的,当且仅当不存在 (1le i< j< k le n, a_i>a_j>a_k)

    证明:咕咕咕

    首先已确定部分如果已经存在以上的不合法情况,或者不管怎么填都不可能合法,那么答案为 (0)

    观察已确定的部分的最大值 (x),那么容易发现剩下的数中小于 (x) 的应该按升序排。于是想到先处理大于 (x) 的部分,然后再把小于 (x) 的插进去。

    • 对于大于 (x) 的部分,可以看作一个长度为 (n-x) 的好的排列的问题;
    • 然后插入小于 (x) 的数,注意到小于 (x) 的数之前不能有大于 (x) 的部分的逆序对。

    于是发现,对于大于 (x) 的部分的一种填法,接下来插入小于 (x) 的数的方案数只与 第一个 逆序对结束点 的位置 有关。

    考虑 DP 解决。(f_{i,j}) 表示长度为 (i) 的「好」排列中,有多少个的第一个 逆序对结束点 在 (j)。(特别地,如果不存在逆序对,那么规定第一个逆序对结束点为 (n+1)

    可以得到 (f_{i,j}=sum_{k=j-1}^{i}f_{i-1,k}),边界 (f_{i,1}=0,f_{1,2}=1)。(考虑枚举最小值的位置即得转移方程)

    很明显 (f_{i,j}=f_{i,j+1}+f_{i-1,j-1})。至此,我们所做的 (Theta (n^2)) 的。要看看能不能优化。

    打表出来发现它跟卡特兰数有关,于是我们试着往卡特兰数的方向去靠。

    于是想到 (f_{i,j}) 相当于从 ((1,2)) 走到 ((i,j)),每一步只能往下或者往右上走,且不能走到直线 (y=1) 上的方案数。

    这又相当于从 ((0,0)) 走到 ((2i-j,j-2)),每一步只能往右下或者右上走,且不能走到直线 (y=-1) 上的方案数。这是经典问题,答案为
    ({2i-jchoose i-1}-{2i-jchoose i}),你可以参考 这里

    那么答案为 (sum_{j=2}^{n-x+1}left[{2(n-x)-jchoose n-x-1}-{2(n-x)-jchoose n-x} ight]{j-1+x-mchoose x-m})

    还可以再化简!

    (sum_{j=2}^{n-x+1}left[{2(n-x)-jchoose n-x-1}-{2(n-x)-jchoose n-x} ight]{j-1+x-mchoose x-m}\ =sum_{j=2}^{n-x+1}{2(n-x)-jchoose n-x-1}{j-1+x-mchoose x-m}-sum_{j=2}^{n-x}{2(n-x)-jchoose n-x}{j-1+x-mchoose x-m}\ =[{2n-m-xchoose n-m}-{2n-2x-1choose n-x-1}]-[{2n-m-xchoose n-m+1}-{2n-2x-1choose n-x}]\ ={2n-m-xchoose n-m}-{2n-m-xchoose n-m+1} )

    现在我们来考虑原问题。

    由于我不想算字典序严格大于 (q) 的「好」排列个数,所以容斥一下,答案就等于好的排列总数减去字典序不大于 (q) 的「好」排列个数。

    从前往后考虑 前 ((i-1)) 位与 (q) 的前 ((i-1)) 位相同 但 第 (i) 位比 (q_i) 小 且 符合条件 的排列有多少个。根据刚才得到的式子,我们发现有解时答案只和 (n,m,x) 有关,所以

    • (q_i< max_{j=1}^{i-1}q_j) 时,

      • 如果在 ([1,q_i)) 内都填过了,那这一位没有贡献;
      • 如果还有没填过的,那容易发现,这一位必须填没填过的当中最小的一个数,并且因为连 (q_i) 都填不了,后面的答案都是 (0) 了,只能 break 掉;
    • (q_i> max_{j=1}^{i-1}q_j) 时,如果想选 ([1,max_{j=1}^{i-1}q_j)) 内的东西,一样的只能选最小的那个,但这时不用 break 掉;否则暴力往上推即可,这个一共只会推 (O(n)) 次。

    最后要算上 (q) 自己的好坏。

    只要维护一个 (operatorname{mex}),不用树状数组,时空复杂度 (O(n))

  • 相关阅读:
    jsf+ejb
    java CDI
    Android5.0新特性——阴影和剪裁(shadow)
    Android5.0新特性——图片和颜色(drawable)
    Android5.0新特性——全新的动画(animation)
    Android SDK Tools和Android SDK Platform-tools
    Android5.0新特性——Material Design简介
    emulator: ERROR: x86 emulation currently requires hardware acceleration!
    Android应用与系统安全防御
    JSON数据解析(转)
  • 原文地址:https://www.cnblogs.com/Camp-Nou/p/13541629.html
Copyright © 2011-2022 走看看