String painter
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.
Output
A single line contains one integer representing the answer.
Sample Input
zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd
Sample Output
6
7
解题思路:
还是一道区间DP。不过有点难,想了很久没想出来最后是看了别人的题解才写出来。
直接DP写不出来。用一点技巧,先用一个空串刷成目标串,区间DP计算最优解。
转移方程:
dp[j][ends] = min(dp[j+1][ends],dp[j][ends-1])+1;
for(int k = j+1 ; k <= ends; k ++)
{
if(s2[k] == s2[j]) // s[j]与s[k]相同 可以dp[j][k]和dp[j+1][k]等价
dp[j][ends] = min(dp[j][ends],dp[j+1][k]+dp[k+1][ends]);
}
然后再进行一次DP求解答案。可以想到如果当前位置两个串的值相等那么res[i]和res[i-1]是等价的,因为当前点可以不刷。然后再枚举一遍分割点
转移方程:
if(s1[i] == s2[i])
res[i] = res[i-1];
else
{
for(int j = 0; j < i; j ++)
res[i] = min(res[i],res[j]+dp[j+1][i]);
}
AC代码:
//#include <bits/stdc++.h>
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <cstring>
#include <utility>
#include <string>
#define INF 0xfffffff
#define int long long
using namespace std;
const int mod = 1e4+7;
const int N = 1e2+10;
int res[N];
int dp[N][N];
signed main()
{
string s1,s2;
while(cin>>s1>>s2)
{
int sz = s1.size();
memset(dp,0,sizeof(dp));
memset(res,0,sizeof(res));
for(int i = 1 ; i <= sz ; i++)
{
for(int j = 0 ; j <= sz+1-i ; j ++)
{
int ends = j+i-1;
dp[j][ends] = min(dp[j+1][ends],dp[j][ends-1])+1;
for(int k = j+1 ; k <= ends; k ++)
{
if(s2[k] == s2[j])
dp[j][ends] = min(dp[j][ends],dp[j+1][k]+dp[k+1][ends]);
}
}
}
for(int i = 0; i < sz; i ++)
res[i] = dp[0][i];
for(int i = 0 ; i < sz ; i++)
{
if(s1[i] == s2[i])
res[i] = res[i-1];
else
{
for(int j = 0; j < i; j ++)
res[i] = min(res[i],res[j]+dp[j+1][i]);
}
}
cout<<res[sz-1]<<endl;
}
return 0;
}