模拟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-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)$

你可能感兴趣的:(模拟71 题解)