String painter
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6988 Accepted Submission(s): 3381
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
题目大意:先给你两个字符串,要求用最少的刷漆次数让s1=s2,一次可以把第一个字符串中的一段区间内的所有字母都换成同一个字母
思路:两次dp处理,第一次dp把一个空白字符串转化成目标字符串需要的次数表示出来,dp[ i ][ j ]表示把区间[i , j]内的字符串转化成目标串需要的次数
第二次dp在第一次的基础上,表示将当前串转化成目标串需要的次数,用ans[ i ]表示
#include<iostream> #include<string.h> using namespace std; char s1[105],s2[105]; int ans[105],dp[105][105]; //两次dp处理 //dp[i][j]表示将一个空白字符串刷成目标字符串需要的次数,i,j分别表示字符串开始和结束的位置 //ans[i]表示在dp[i][j]的基础上,将当前字符串表示成目标字符串需要的次数 int min(int a,int b) { return a>b?b:a; } int main() { while(cin>>s1>>s2) { int len=strlen(s2); for(int j=0;j<len;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(s2[i]==s2[k]) dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]); } } } for(int i=0;i<len;i++)//将当前串处理成目标串 ans[i]=dp[0][i]; for(int i=0;i<len;i++) { if(s1[i]==s2[i])//相同就不刷 ans[i]=ans[i-1]; else { for(int j=0;j<i;j++) ans[i]=min(ans[i],ans[j]+dp[j+1][i]); } } cout<<ans[len-1]<<endl; } return 0; }