小小粉刷匠升级版(区间dp)
String painter
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6211 Accepted Submission(s): 2992
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,一次只能将一个区间刷一次,问最少几次能让s1=s2
题解:看到区间,又是找最少操作次数,想到区间DP。
思路:直接将A转化成B不好办,我们可以先将一个空串转化成B,再比较将A直接妆化成B那个更快;
令dp[i][j]为将[i, j]区间转换成功最少操作数;
下一步的工作就是看看A直接转换成B是否更快?
令ans[i]表示A的[0, i]区间转换成B的[0, i]的最少操作;
最坏情况下,A->B,相当于空串->B;ans[i]=dp[0][i];
如果A[i]==B[i] , ans[i]=ans[i-1];这一步其实也很容易理解,i处的字符相等,那么就不需要转化了,只要转化前i-1字符;
[1, i]转换后,看看还有没有更简便的;
ans[i]=min(ans[i], ans[j]+dp[j+1][i])(1<=j<i);
#include<bits/stdc++.h> #include<cstdio> using namespace std; const int MMAX=1e2+5; char s1[MMAX],s2[MMAX]; int dp[MMAX][MMAX]; int ans[MMAX]; int main() { while(~scanf("%s",s1+1)) { scanf("%s",s2+1); int len=strlen(s1+1); for(int i=1;i<=len;i++) dp[i][i]=1; for(int le=2;le<=len;le++) ///枚举长度 { for(int l=1;l<=len-le+1;l++) ///枚举起点 { int r=l+le-1; ///确定终点 dp[l][r]=dp[l+1][r]+1; ///dp数值初始化 for(int k=l+1;k<=r;k++) ///枚举断点 { if(s2[l]==s2[k]) { if(k==r) dp[l][r]=min(dp[l][r],dp[l+1][r]); else dp[l][r]=min(dp[l+1][k]+dp[k+1][r],dp[l][r]); } else dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]); } } } ans[0]=0; for(int i=1;i<=len;i++) { ans[i]=dp[1][i]; if(s1[i]==s2[i]) ans[i]=ans[i-1]; for(int j=1;j<i;j++) ans[i]=min(ans[i],ans[j]+dp[j+1][i]); } printf("%d\n",ans[len]); } return 0; }

浙公网安备 33010602011771号