闲扯
我太难了!!!
题面
$T1$
Solution
我们考虑 $DP$ 。
设 $DP_{i,j}$ 表示 $(i-1,j-1)$ 都匹配成功,在 $(i,j)$ 处失配,其最短公共非子序列的长度, $dp_{0,0}$ 显然是 $0$ 。
考虑转移。
我们只在 $s_i=t_j$ 处转移。
假设最近下一处 $s_{i’}=t_{j’}$ 那么 $dp_{i’,j’}=\min(dp_{i’,j’},dp_{i,j}+1)$ 。
这是因为在此之间不存在相同的东西,所以我们将下一个定为 $s_{i’}$ ,一定可以保证 $(i’-1,j’-1)$ 不包含当前的串。
最后的答案就是 $dp_{n+1,m+1}$ 。
还需要解决是字典序。
我们将状态看做点,那么我们找的实际上就是一个图中 $(0,0)$ 到 $(n+1,m+1)$ 的最短路。
那么我们可以先将最短路树建出来(从 $(n+1,m+1)$ 开始倒着建),然后再贪心的走即可。
Code
1 |
|
$T2$
Solution
首先明确一点:我们某一个数的选择次数一定是形如 $2^k-1$ 的。
因为对于一个 $popcnt=k$ 的点,我们将中间的 $0$ 去掉,消费一定更少。
然后我们可以贪心的来进行选取。
每次取出一个形如 $2^k*i$ 的数,表示 $i$ 这个数,从 $2^0,2^1,\cdots,2^{k-1}$ 都选过了,这一次增加 $2^k$ 个,而答案加 $1$ 。
我们可以用一个优先队列维护一下,每次取出一个 $2^ki$ 最小的数,答案加 $1$ ,然后加入 $2^{k+1}i$ 。
考虑优化这个过程。
我们可以发现,我们每次选的这个数是单调不减的,所以我们可以二分一个 $M$ ,表示所有代价不超过 $M$ 的形如 $2^k*i$ 的数我们全部选择。
然后判断是否超过 $n$ 。
我们找到一个最大的 $M$ 后,可能还剩了一些数。
我们再加上 $\lfloor\frac{rest}{M+1}\rfloor$ ,就是最后的答案。
这表示代价为 $M+1$ 的数我们没法选完,但是可能选择部分。
(不存在不足 $\lfloor\frac{rest}{M+1}\rfloor$ 个代价为 $M+1$ 的数的可能,因为如果不够,说明可以将 $M+1$ 买完,最后得到的就不是 $M$ 。)
Code
1 |
|
$T3$
Solution
我们从小到大逐渐往中间加数。
对于一个数,我们考虑是左边还是放右边。
如果每一次交换,我们只在较小的那个数上计算,那么每一个数向左的代价就是满足 $i
然后我们贪心的往两边放即可。
对于相同的数,我们可以发现,如果交叉放一定不会更优,所以我们一定是一段全部向左,剩下的全部向右。
用两个指针,从两边向中间贪心的放即可。
Code
1 |
|
总结
这几天不在状态,要抓紧恢复!