HDU 2476 String painter

String painter

Time Limit: 2000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 2476
64-bit integer IO format: %I64d      Java class name: Main
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

Source

 
解题:区间dp
  我们可以先假设最坏的情况下,把a刷成b,当然是当a是空白的时候 dp[i][j]表示把空串i到j刷成b的i到j需要最少多少步
这时候有dp[i][j] = min(dp[i][j],dp[i+1][k]+dp[k+1][j]) 当b[i] == b[k]的时候
 
为什么是dp[i+1][k]+dp[k+1][j]呢 因为刷k的时候 我们可以同时把i给刷掉在b[i] == b[k]的时候
 
现在的问题是a不是空白的,那么我们该如何处理
 
ans[i] = min(ans[i],ans[j]+dp[j+1][i])
 
把j+1到i这段 看成是空串刷过来的
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 120;
 4 int dp[maxn][maxn],ans[maxn];
 5 char a[maxn],b[maxn];
 6 int main() {
 7     while(~scanf("%s%s",a,b)) {
 8         int n = strlen(a);
 9         memset(dp,0,sizeof dp);
10         for(int i = n-1; i >= 0; --i)
11             for(int j = i; j < n; ++j) {
12                 dp[i][j] = dp[i+1][j] + 1;
13                 for(int k = i+1; k <= j; ++k) {
14                     if(b[i] == b[k])
15                         dp[i][j] = min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
16                 }
17             }
18         memset(ans,0x3f,sizeof ans);
19         for(int i = 0; i < n; ++i) {
20             if(a[i] == b[i]) ans[i] = i?ans[i-1]:0;
21             else ans[i] = dp[0][i];
22             for(int j = i-1; j >= 0; --j)
23                 ans[i] = min(ans[i],ans[j]+dp[j+1][i]);
24         }
25         printf("%d\n",ans[n-1]);
26     }
27     return 0;
28 }
View Code

 

posted @ 2015-07-22 19:08  狂徒归来  阅读(201)  评论(0编辑  收藏  举报