Balanced String
这道题目真的不知道怎么总结了,这技巧太新了
见这篇题解
为什么最开始要引入这个子问题呢?实际上,我们假设我们已经得到了最终的交换后的答案,设为\(t\),\(s\)就是题目给的原串,从\(s\)到\(t\)的最小交换次数当然就是从\(t\)到\(s\)的最小交换次数,于是考虑从\(t\)到\(s\)的最小交换次数,发现是\(s,t\)不相等的位置的个数
接下来的DP就围绕这个个数做文章。我们抛开题目的交换操作不看,直接构造\(t\):每一个位置可以随便填\(0/1\),\(f_{i,j,k}\)记录的就是所有长度为\(i\)的\(0/1\)串(一共有\(2^i\)个),满足所给条件的与\(s\)前\(i\)个字符不同的位置的最小个数。然后直接考虑\(f_{n,cnt,0}\)(其中\(cnt\)是\(s\)中\(0\)的个数),这个\(f\)根据最开始的子问题的分析,就是答案
update 2024.8.28
稍微想了一个简单一点的:假设我们已经获得了最终的答案\(t\),可以发现最小交换次数就是\(s\)与\(t\)不同的位置的个数;于是设\(f[i][j][k]\)表示对于\(s\)前\(i\)个字符,将\(0\)改成\(1\)的个数减去将\(1\)改成\(0\)的个数的差为\(j\),"10"减去"01"的个数为\(k\)的最小的将\(0\)改成\(1\)的个数,DP即可;最终答案为\(f[n][0][0]\)
但是这里要用滚动数组优化,记住滚动数组每次进入循环都要重新初始化,而且为了不超时,转移的时候一定要加上判断,保证由于转移的状态是上个阶段的合法状态