2476 , H
Problem Describe
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
題意 : 每次能將一個區間裡面的字母改成一個同一個字母,問最少需要多少次將str1串變成str2串
思路 : 這個題感覺很怪 ,明顯的區間dp ,可是偏偏無從下手 , 它每次dp的時候str1 串 和 str2串匹配的時候總是感覺很難搞 , 用平常的區間dp寫了一下 WA了 , 於是菜的我去搜了題解 發現區間 dp 還可以這樣搞 ,神奇 吶~~
AC code :
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 110 ;
int dp[maxn][maxn] ,len ,ans[maxn] ;
char str1[maxn] ,str2[maxn] ;
int main() {
while(~scanf("%s %s",str1 + 1 ,str2 + 1 )) {
len = strlen(str1 + 1) ;
memset(dp ,0 , sizeof(dp) ) ;
memset(ans ,0 ,sizeof(ans) ) ;
for (int i = 1 ; i <= len ; i ++) {
for (int j = i ; j <= len ; j ++ ) {
dp[i][j] = j - i + 1 ;
}
}
for (int l = 2 ; l <= len ; l ++ ) {
for (int i = 1 ; i <= len - l + 1 ; i ++) {
int j = i + l - 1;
if ( str2[i] == str2[j] ) dp[i][j] = dp[i][j-1];
else dp[i][j] = dp[i][j-1] + 1;
for (int k = i ; k <= j - 1 ; k ++ ) {
dp[i][j] = min(dp[i][j] ,dp[i][k] + dp[k+1][j] ) ;
}
}
}
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];
}
for (int j = 1 ; j <= i - 1 ; j ++ ) {
ans[i] = min(ans[i] ,ans[j] + dp[j+1][i] );
}
}
printf("%d\n",ans[len]);
}
return 0;
}