模拟71 题解
A. 毛一琛
暴搜复杂度$O(3^n)$,所以显然的优化是$meet\ in\ the\ middle$ ,
可以优化为$O(\sum \limits_{i=1}^{n} \binom{n}{i}2^{\frac{i}{2}})$。
只要将每个状态都分成两半,分别求出可能的方案,再枚举左侧一种方案,找对应的方案就可以了。
然而常数打丑确实会挂成暴力不如的分数。
B. 毛二琛
设$pos_i$表示$i$出现的位置,有$pos_{a_i}=i$。
那么对于排列$s$中的数,如果想换到$p$的对应位置,需要满足一些条件。
可以进行讨论:
如果$pos_i=i$,那么无论如何交换都不可能满足,必死。
如果$pos_i<i$,那么该位置需要不断向左交换。
那么可以加入一些限制,
为了防止i被换到右边,第$i-1$次交换必须发生在第$i$次交换之前。
为了不断左移,第$i-k$次交换必须发生在第$i-k-1$次交换之前。
为了防止左移过$pos_i$,第$pos_i-1$次交换必须发生在第$pos_i$次交换之前。
如果$pos_i>i$,情况是类似的。
所以每两位之间存在一些限制。
如果出现环,那么必定无解。
因为边只有$n-1$条,问题其实就是树形有向图的拓扑序数量。
然而只是在链上,所以形式更加简单。
设$f_{i,j}$表示考虑前$i$个位置,第$i$个位置在前$i$个位置的拓扑序排名为$j$。
那么转移是显然的,只是简单前缀,后缀和。
C. 毛三琛
正解很诡异,但是确实是正确的。
将所有的$x$放在数组里,进行$random_shuffle$。
那么考虑按数组下标的顺序考虑每一个$x$。
显然答案是单调的,如果在$+x$意义下当前最优答案已经不合法,那么可以直接考虑下一个x。
否则继续进行二分。
在大多数情况下,这个算法的复杂度是正确的。
设$x_i$对应的答案为$ans_i$。
那么$ans_i$存在一个从大到小的排名。
如果$ans_i$为最大元素,那么一定进行二分,贡献为1。
如果$ans_i$为次大元素,那么进行二分的条件是最大值不出现在它的左侧,贡献为1/2。
同理从大到小考虑每一个元素。
复杂度为$O(\sum \limits_{i=1}^{n}\frac{1}{i}*nlog)=O(nlog^2)$