CF 477 D Dreamoon and Binary 题解
CF 477 D Dreamoon and Binary
这题比较easy。
首先可以发现是dp。
可以设dp状态为\(dp[i][j]\)。表示[i,j]。
每一个状态存储两个值: 最小次数,再次基础上的操作次数
我们就叫它们fir和sec吧。
初始化\(dp[0][0]=\{0,0\}\)
可以发现一个比较显然的转移:
\[dp[i][j]=merge(merge_{k<i-1} dp[k][i-1],dp[i-len][i-1]\mid (s_{i-len...i-1}\leq s_{i...j})),(len=j-i+1)
\]
merge函数如下:
merge({A,B},{C,D})
if(A!=C) return min({A,B},{C,D});
else return {A,B+D};
可以发现这个前面一半搞一个后缀和。那么问题就转换成,对于一个\((i,j)\),判断\(s_{i-len...i-1}\)和\(s_{i...j}\)的大小关系。
这玩意可以通过二分找到相同的前缀,然后比较。但是这样复杂度是\(O(N^2\times \log n)\),可能会被卡常。
不过我们可以另外开一个数组: \(common[i][j]\)表示最大的x,满足\(s_{i...i+x-1}=s_{j...j+x-1}\)
这样跑\(N\)遍\(z-algorithm\)就可以了。时间复杂度为\(O(N^2)\)。