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
分析:
题意:
给出两个长度相等的字符串str1和str2,对str1连续的字符进行操作可以变成str2,请问至少多少次操作可以变成str2?
解析:
我看了很久,没有思路,然后瞄了一眼题解,然后就写了一个一直WA的代码!
我们设置一个dp数组,用dp[i][j]表示从第i个字符到第j个字符的做少操作次数:
(1)如果str2[i]==str2[j],那么就可以在第j个字符处做出划分;
(2)如果str2[i]!=str2[j],那么dp[i][j]=dp[i][j-1]+1;
那么我们就可以写出关键的代码:
for(int j=1;j<=len1;j++)
{
for(int i=j;i>0;i--)
{
dp[i][j]=dp[i+1][j]+1;
for(int k=i+1;k<=j;k++)
{
if(str2[i-1]==str2[k-1])
dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
}
}
}
开始第二个循环我是按照正序写的,所以一直WA,经过一个多小时的仔细想,终于发现错在哪里了!就是k的取值对这里有影响,dp[k+1][j],按照正序,则dp[k+1][j]的结果并不是最优的值,因为还未计算!
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 105
using namespace std;
int dp[N][N];
int sum[N];
int main()
{
string str1,str2;
while(cin>>str1>>str2&&!str1.empty())
{
memset(dp,0,sizeof(dp));
int len1=str1.length();
for(int j=1;j<=len1;j++)
{
for(int i=j;i>0;i--)
{
dp[i][j]=dp[i+1][j]+1;
for(int k=i+1;k<=j;k++)
{
if(str2[i-1]==str2[k-1])
dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
}
}
}
for(int i=1;i<=len1;i++)
{
sum[i]=dp[1][i];
}
for(int i=1;i<=len1;i++)
{
if(str1[i-1]!=str2[i-1])
{
for(int j=1;j<i;j++)
{
sum[i]=min(sum[j]+dp[j+1][i],sum[i]);
}
}
else
{
sum[i]=sum[i-1];
}
}
printf("%d\n",sum[len1]);
}
return 0;
}