DTOJ #5873. 求求你别排队了 题解
作者:互联网
求求你别排队了
先解释下最优策略:对于两种策略,选择期望逆序对个数少的。
首先有几个显然的事实:
- 如果当前逆序对个数小于操作次数,则可以直接通过交换使逆序对个数归零。
- 策略必定是先多次随机,然后剩下次数交换。
我们考虑记 f[n][k]
表示对于一个随机的 \(n\) 排列,还能操作 \(k\) 次的期望逆序对个数。
显然,对于一个确定的 \(n\) 排列,设其逆序对个数为 \(m\)。
- 若 \(m\le k\),显然可以不断交换,转移到 \(0\)。
- 若 \(m>k\),此时不能不断交换到 \(0\):
- 但可以不断交换到逆序对个数为 \(m-k\)。
- 当然也可以来一次 BogoSort,即转移到
f[n][k-1]
。 - 我们对两者取 \(\min\) 即可。
不过这是对于一个确定的 \(n\) 排列。对于随机的显然不可能去枚举每个确定的排列然后转移。
不过我们可以记 C[n][m]
表示逆序对个数为 \(m\) 的 \(n\) 排列的方案数,考虑如何转移:
考虑加入一个数 \(n\)。
\(n\) 可以插在最后一个,逆序对贡献为 \(0\);倒数第二个,逆序对贡献为 \(1\);倒数第三个……
显然有下面这个递推式:
直接转移 \(O(n^4)\),但相信正常人都会做到 \(O(n^3)\) 或者更低。
不过会发现 C[n][m]
显然会爆 long long
。我们考虑不记数量,转记概率 P[n][m]
。这样对 f[n][k]
也会更好转移(不用乘 \(n!\) 逆元)
然后可以写出 f[n][k]
的递推式了:
解释一下,这里 \(i\) 是在枚举这个 \(n\) 排列的逆序对个数,对于 \(i\le k\) 显然直接交换得到 \(0\),对于 \(i>k\) 考虑 BogoSort 和 直接交换 中较小的一个。
显然,f[n][k]
和 f[n-1]
没有半毛钱关系,可以只记一维。
上面这个转移是 \(O(n^2m)\) 的,考虑优化。
右边那个 \(\min\) 显然有搞头,当 \(f_{k-1} < i-k\) 的时候,右边是常值,可以直接拿 P[n][m]
的前缀和乘。
但这样不知道能优化多少。
我们输出一下 f[k]
,发现在 \(k\) 较大时 \(f_k\approx0\),几乎就是 \(O(1)\) 转移了。并且如果把循环次数累加起来输出的话,会发现不超过 \(10^8\)。
所以时间复杂度 \(O(n^3)\sim O(10^8)=O(n^3)\sim O(1)\)。能通过此题。
至于题目事先给了确定的排列,我们直接在第一步选择 BogoSort 转移到 f[m-1]
或者暴力交换转移到 \(\sigma(a_1,a_2,\cdots,a_N)-m\)。
标签:排列,题解,个数,显然,5873,你别,交换,转移,逆序 来源: https://www.cnblogs.com/lingfunny/p/16342401.html