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这段 看成是空串刷过来的
 
HDU 2476 String painter
 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

 

你可能感兴趣的:(String)