区间DP:string painter

string painter

There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string painter. With the help of the painter, you can change a segment of characters of a string to any other character you want. That is, after using the painter, the segment is made up of only one kind of character. Now your task is to change A to B using string painter. What’s the minimum number of operations?
Input:
Input contains multiple cases. Each case consists of two lines:
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.
Output:
A single line contains one integer representing the answer.
Sample Input:
zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd
Sample Output:
6
7
有两个长度相等的字符串A和B。两个字符串都由小写字母组成。现在您有了一个强大的字符串绘制器。在绘图器的帮助下,您可以将字符串的一段字符更改为您想要的任何其他字符。也就是说,在使用了画家之后,这个片段只由一种角色组成。现在您的任务是使用string painter将A更改为B。最小操作数是多少?输入输入包含多个案例。每个案例由两行组成:第一行包含字符串A。第二行包含字符串B。两个字符串的长度都不会大于100。输出一行包含一个表示答案的整数。样例输入:
zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd
样例输出:
6
7
这题对新手是真的不友好,还是要自己手动算一下才能理解。基本思路是:开始先对dp数组初始化,就是递进的初始化(如dp[0][0]=1,dp[0][1]=1,dp[0][2]=2),然后对每一个子区间,寻找与第一个元素相等的元素,若存在,则将首元素去掉,进行优化(因为相等元素很大可能是同一次刷上的),最后再对ans数组进一步优化。

#include <bits/stdc++.h>
using namespace std;
char s1[105],s2[105];
int dp[105][105];
int ans[105],i,j,k,len;
int main()
{
    while(~scanf("%s%s",s1,s2))
    {
        len = strlen(s1);
        memset(dp,0,sizeof(dp));
        for(j = 0; j<len; j++)
        {
            for(i = j; i>=0; i--)
            {
                dp[i][j] = dp[i+1][j]+1;//dp数组初始化
                for(k = i+1; k<=j; k++)
                {
                    if(s2[i]==s2[k])
                        dp[i][j] = min(dp[i][j],(dp[i+1][k]+dp[k+1][j]));//第二个可以看出去掉了首元素
                }
            }
        }
        for(i = 0; i<len; i++)
            ans[i] = dp[0][i];//ans数组初始化
        for(i = 0; i<len; i++)
        {
            if(s1[i] == s2[i])
                ans[i] = ans[i-1];//若相等,则直接顺承上一个的ans就行了
            else
            {
                for(j = 0; j<i; j++)
                    ans[i] = min(ans[i],ans[j]+dp[j+1][i]);
            }
        }
        printf("%d\n",ans[len-1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/soul_mingling/article/details/87928704