1. 程式人生 > >2476 , H

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; }