String painter
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4750 Accepted Submission(s): 2237
Problem Description
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.
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
Source
Recommend
题意是给出2个字符串,每次对1串操作可以将任意一个区间内的字符转化为相同的任意一个字母,问最少操作多少次可以将1串变成2串;
最坏情况是对1串的每一个字符进行处理,那么初始化dp数组则是按照最坏情况,然后对2串进行遍历,如果发现有相同的字符,则可以进一步优化dp数组,然后就是对1串和2串进行同时遍历,对于相同位置上的字母如果相同,则操作数是和上一长度的操作数一样的,如果不相同,则在之前长度里面找到一个位置来找最小值,这里的状态优化:ans[i]=min(ans[i],ans[j]+dp[j+1][i])。其中j为从0到i-1中找的中间位置。
#include<iostream>
#include<cstring>
using namespace std;
int main(){
char a[111],b[111];
int dp[111][111];
int ans[111];
int len;
int i,j,k;
while(cin>>a>>b)
{
int i,j,k;
len=strlen(a);
memset(dp,0,sizeof(dp));
for(i=0;i<len;i++)
{
for(j=i;j>=0;j--)
{
dp[j][i]=dp[j+1][i]+1;
for(k=j+1;k<=i;k++)
{
if(b[j]==b[k])
{
dp[j][i]=min(dp[j][i],dp[j+1][k]+dp[k+1][i]);
}
}
}
}
for(i=0;i<len;i++)
ans[i]=dp[0][i];
for(i=0;i<len;i++)
{
if(a[i]==b[i])
ans[i]=ans[i-1];
else
{
for(j=0;j<i;j++)
ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
}
}
cout<<ans[len-1]<<endl;
}
return 0;
}