Educational Codeforces Round 74
大意
前m个字母的所有排列中
对于字符串s
求min{sum{f(s[i-1],s[i])}}
,i = [1,len(s)-1]
f(char1,char2) = 在所选排列中 这两个char的下标差的绝对值
数据范围
1<=m<=20
1<=len(s)<=100000
1s
256MB
题解
显然把 字符串处理为统计信息一个m*m
的表M
其中M[char1][char2]
表示 字符char1
和char2
相邻的次数
然后看到 20/12都应该想一想 bitdp
dp[state] 表示前 bitcount(state)个数选择了state时的最优代价;
那么我们在 这个状态后面 添加一个未选取的数v
那么 [选取的数的状态][数字v]
问题来了
前面的最优状态如果没有具体位置,那么 v到已经选择的数字的 距离不同,所以权重也就不同,而即使 在最优代价中加上具体状态的记录,也不满足 子最优必定父最优
怎么把 选取的数字的顺序无关化?
考虑已经完全选好的一个排列
xyzabc
那么这个贡献 也就是 dis(x,y)*M[x][y]+dis(x,z)*M[x][z]+....+dis(b,c)*M[b][c]
如果我们画图把 这些点用线连起来
从中间切一刀,例如从xyz|abc这里切分, 会发现 a连出的线条数和 左边排列顺序无关,只和左边个数以及a相对于分割线的位置有关,
考虑 xyz|abc -> xyza|bc
,xya|zbc -> xyaz|bc
所以上面dp[state]的描述 改为 bitcount(state)个数选择了state时,且向右连线到分界线时的最优代价
注意新的分界线 增加的值和老的分界线 没有关系 所以只需要 O(m^2 * 2^m)
而不是 m^3
代码
1 |
|