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
例如zzzzzfzzzzz,长度为11,我们就将下标看做0~10
先将0~10刷一次,变成aaaaaaaaaaa
1~9刷一次,abbbbbbbbba
2~8:abcccccccba
3~7:abcdddddcba
4~6:abcdeeedcab
5:abcdefedcab
这样就6次,变成了s2串了
第二个样例也一样
0
先将0~10刷一次,变成ccccccccccb
1~9刷一次,cdddddddddcb
2~8:cdcccccccdcb
3~7:cdcdddddcdcb
4~6:cdcdcccdcdcb
5:cdcdcdcdcdcb
最后竟串尾未处理的刷一次
就变成了串2cdcdcdcdcdcd
所以一共7次
思路:这种球区间最优解的,明显就是区间DP了- -,需要注意的是,要将1串变为2串,可以说,主要是看2串两个相同字符之间的区间
区间DP的题目技巧性一般都很强,一个字符串的刷法比较好想,两个的刷法有点难,需要好好理解;
这题思路有点吊,先预处理串2,最坏情况没有串1需要刷几次,再处理串1,如果有相同,DP思想找最优
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<cstring>
#include<vector>
#include<queue>
#include <bits/stdc++.h>
using namespace std;
const int N = 507;
const int inf = 0x3f3f3f3f;
const int maxn=1e6+2;
typedef long long LL;
char str1[N], str2[N];
int dp[N][N],ans[N];
int main()
{
while(scanf("%s %s",str1+1, str2+1)!=EOF)
{
int len=strlen(str1+1);
memset(dp,0,sizeof(dp));
for(int i=1;i<=len;i++) dp[i][i]=1;
for(int l=1;l<=len;l++)
{
for(int i=1;i+l<=len;i++)
{
int j=i+l;
if(str2[i]!=str2[j]) dp[i][j]=dp[i][j-1]+1;
else dp[i][j]=min(dp[i][j-1],dp[i+1][j]);
for(int k=i+1;k<j;k++)
{
if(str2[i]==str2[k]) dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
}
}
memset(ans,0,sizeof(ans));
for(int i=1;i<=len;i++) ans[i]=dp[1][i];
for(int i=1;i<=len;i++)
{
if(str1[i]==str2[i]) ans[i]=ans[i-1];
else
{
for(int j=1;j<i;j++) ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
}
}
cout<<ans[len]<<endl;
}
return 0;
}