一、题意:给定一个长度最多为50的串S,求用最少的步数将S变成由两个相同的串连接而成的,所用的方法可以是(假设原始串S为aaba):
1、删除串中一个特定字符,eg.aaba-->aba;
2、在串S的任意的位置添加一个字符,eg.aaba-->aabba;
3、修改串S的任意一个字符,eg.aaba-->aaaa;
题外话:由于省赛的时候见过此类字符串最少修改次数的题目,当时不会做,大牛说是用构造图,然后bfs完成的。当然那题与此题不相同。
二、分析:由于串S的最终是要变成两个相同子串的拼接,因此,我们可以将S分割成两个子串s1和s2,通过dp来获得最少修改步数使得两个子串相等,通过枚举在串S上的分割点得到当前状态对应的最少修改步数,从而获得全局的最少修改步数。
dp[i][j]表示s1长度为i,s2长度为j,s1和s2相同最少需要的修改的步数
1、当s1[i]==s1[j]的时候,我们不需要修改任何字符;
2、当s1[i]!=s2[j]时,我们可以有五种方法处理:
2-1、在s1[i]位置插入一个s2[j]字符,来达到这两个位置对应的字符相等,此时需要需要一步修改,即dp[i][j]=dp[i-1][j]+1;
2-2、在s2[j]位置插入一个s1[i]字符,此时同样需要一步修改,即dp[i][j]=dp[i][j-1]+1;
2-3、把s1[i]位置的字符删除掉,此时新得到的状态相当于由dp[i][j-1]状态转变过来,即dp[i][j]=dp[i][j-1]+1;
2-4、把s2[j]位置的字符删除掉,即dp[i][j]=dp[i-1][j]+1;
2-5、把s1[i]位置的字符修改成s2[j]位置对应的字符或者反过来,此时相当于从状态dp[i-1][j-1]转变过来,即dp[i][j]=dp[i- 1][j-1]+1;
因此得到的状态方程为:
|-----dp[i-1][j-1];.................................................(s1[i]==s2[j])
dp[i][j]=|
|-----min{dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1;........(s1[i]!=s2[j])
串s1(长度len1),串s2(长度len2)对应的最少修改步数为dp[len1][len2]。
菜鸟毕竟是菜鸟,刚看到RoBa用了相当少的时间就搞定了此题。