AGC066 D. A Independent Set
题目链接:https://atcoder.jp/contests/agc066/tasks/agc066_d
题目大意:给你一个 $AB$ 串,保证 $A\le \frac{n + 1}{2}$ ,每次可以交换 $i$ 和 $i + 1$ 的字符,代价为 $w_{i + 1}$ ,要求最小的代价满足:任意两个 $A$ 不相邻。
我的做法
观察到一个事情:考任意一种可能成为最优方案的方案,一定可以表示成某几个位置的展开。
展开的意思是是说:选择一个 $A$ ,然后从左到右依次将 $A$ 推开,直到某个小区间内没有 $A$ 相邻。
举个例子:$BBBAAABBB$ ,选择中间的 $A$ ,那么中间的 $A$ 就会想着把周围的 $A$ 推开,推成:$BBABABABB$ 。
证明的话,考虑每个 $A$ 是往左移还是往右移的,显然,每一段往左移和每一段往右移中间存在一个数字是不动,否则一定可以更加优秀,所以,每一个不动和左边的往左移动,和右边的往右移动构成了上面所描述的一个小区间。
那么处理出所有的这些区间就行了,处理方法就是把 $A$ 看成 $1$ ,把 $B$ 看成 $-1$ ,然后在折线法左右第一次出现等高的位置,就是区间的左右端点。
然后转移就行了,时间复杂度 : $O(n)$ 。
1 |
|
不懂啊,感觉完全不如 $BCE$ 难,奇怪的难度评价。
官方题解
好吧,官方题解确实难想。
其先基于这么一个转化:如果在原字符串后面添上 $B$ ,那么原题可以转化为:花最小的代价使得原串可以被分割成 $AB,B$ 。
那么一个观察就是 $AB$ 中的 $A$ 一定不会跨过 $B$ ,否则 $A$ 与这个 $B$ 组合一定更优。
证明要详细写出来可能会比较麻烦,大致就是讨论一下,因为最优方案一定可以写成每个 $A$ 按顺序往某个方案移动,而且 $A/B$ 与 $A/B$ 之间不会交换,根据这个原理讨论一下就行了。
由这个观察,我们可以证明,满足这个观察的最优答案一定可以分成若干段,其中 $[l_i,r_i]$ 满足两个字符串在这个区间上的 $A,B$ 数量一样,且最终字符串要么是 $B$ ,要么是 $ABABAB…AB$ ,那么就能得到下面的 $dp$ 。
设 $dp[i]$ 表示前 $i$ 个字母变成可以分割成 $AB,B$ 的字符串最小代价。
如果 $i$ 后面是 $B$ ,则可以 $dp[i]\to dp[i+1]$ 。
或者可以在后面放 $AB$ ,根据上面的条件可以得到 $dp[i]\to dp[j]+cost(i+1,j)$ ,满足 $[i+1,j]$ 中的 $A,B$ 数量一样,可以注意到,等价于 $A$ 看成 $1$ ,$B$ 看成 $-1$ 后 $s_{i}=s_{j}$ ,而且又显然,$s_{i}$ 只需要更新到后面第一个满足要求的 $j$ 就行了,因为若 $j,k$ 都满足要求的话:$cost(i+1,k)=cost(i+1,j)+cost(j+1,k)$ ,所以只需要 $i\to j\to k$ 就行了。
至于算 $cost$ 的话,注意到,每一段的 $j$ 都是往一个方向移动的,所以可以很方便的算出 $cost$ 。(原因:根据上面的 $dp$ 过程不难得到,这一段的前缀和都是同号的,要么 $>0$ ,要么 $<0$ ,除了整段是 $=0$ 的)
综上,时间复杂度:$O(n)$ 。
这个做法比我的做法难想,但是比我的做法好写。
而且其中很多思考的细节是值得认真想想的,很有意义的一个做法,感觉能想明白这个做法对提升 $dp$ 能力很有帮助。