题目大意
牛牛喜欢回文串,牛妹给了牛牛一个字符串S,牛牛想把S变成回文串 牛牛可以做如下三种操作 1:在任意位置增加一个字符 2:删除一个字符 3:改变一个字符
每种操作都有限定的字符,比如,只能删除'a',增加'b',把'c'变成'd'等等 每种操作都有相应的代价 用M条语句来描述能进行的操作 add c x 表示增加c字符需要x的代价 erase c x表示删除c字符需要x的代价 change c1 c2 x表示将c1 改成c2需要x的代价 求牛牛想要得到回文串需要的最少代价 如果不行输出-1
思路
区间dp,不过需要处理一下字符串之间的转移,大致有两种
-
字符之间转换的最小价值。从字符a转移到字符b,直接转移可能并不是最优的,所以用floyd跑一遍转移的最小花费。
-
字符的删除与增加,删除一个字符,直接删除可能不是最优的,所以spfa跑最短路求删除每个字符的最小花费,增加也是同理。
处理完之后,就可以用区间dp的思路了,从外到内扩展,用记忆化搜索写
dp(l,r)表示将区间l,r变成回文串的最小花费,有几种转移:
-
dp(l,r)从dp(l,r-1)转移过来,需要删除掉s[r]。
-
dp(l,r)从dp(l+1,r)转移过来,需要删除掉s[l]。
-
dp(l,r)从dp(l+1,r-1)转移过来,需要删除两端
-
dp(l,r)从dp(l,r-1)转移过来,可以在左端增加字符v并将s[r]转移为v