HDU 2476 String painter

String painter

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1312    Accepted Submission(s): 554


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

 
Source
 
在程序编写过程中有很多问题,需要理解一下。
 1       for(len=2;len<=n;len++)//枚举长度

 2         {

 3             for(j=len-1;j<n;j++)//枚举终点

 4             {

 5                 i=j-len+1;//起点

 6                 dp[i][j]=dp[i+1][j]+1;

 7                 for(k=i+1;k<=j;k++)

 8                 {

 9                     if(b[i]==b[k])

10                     {

11                         dp[i][j]=Min(dp[i][j],dp[i+1][k]+dp[k+1][j]);

12                     }

13                 }

14             }

15         } 

比较

 1 for(i=0;i<n;i++)

 2         {

 3             for(j=i+1;j<n;j++)

 4             {

 5                 for(k=i+1;k<=j;k++)

 6                 {

 7                     if(b[i]==b[k])

 8                     {

 9                         dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);

10                     }

11                 }

12             }

13         }

 

前者第一个枚举长度,紧接着是枚举终点,和起始点。

后者直接根据递推: dp[ i ] [ j ] = min(dp[i ] [ j ], dp[ i ] [ k ]+dp[ k+1] [ j ]);来做。

两者差异很大,但是感觉后者的不会错,实际上却是有问题的。

因为在更新的过程中,用到的  dp[ k+1] [ j ],可能是没有被更新的。

当dp[ k+1] [ j ]被更新的时候,包含他的所有的dp[ ] [ ] 都没有被更新。

所有要长度开始枚举。

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<cstdlib>

 5 using namespace std;

 6 

 7 int ans[102];

 8 int dp[102][102];

 9 char a[103],b[103];

10 int main()

11 {

12     int i,j,n,len,k;

13     while(scanf("%s%s",a,b)>0)

14     {

15         n=strlen(a);

16         memset(dp,0,sizeof(dp));

17         memset(ans,0,sizeof(ans));

18 

19         for(i=0;i<n;i++)

20             dp[i][i]=1;

21         for(len=2;len<=n;len++)

22         {

23             for(j=len-1;j<n;j++)

24             {

25                 i=j-len+1;

26                 dp[i][j]=dp[i+1][j]+1;

27                 for(k=i+1;k<=j;k++)

28                 {

29                     if(b[i]==b[k])

30                     {

31                         if(k==j)

32                             dp[i][j]=min(dp[i][j],dp[i+1][k]);

33                         else

34                             dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);

35                     }

36                 }

37             }

38         }

39         for(i=0;i<n;i++)

40             ans[i]=dp[0][i];

41         for(i=0;i<n;i++)

42         {

43             if(a[i]==b[i])

44                 ans[i]=ans[i-1];

45             else

46             {

47                 for(j=0;j<=i;j++)

48                     ans[i]=min(ans[i],ans[j]+dp[j+1][i]);

49             }

50         }

51         printf("%d\n",ans[n-1]);

52     }

53     return 0;

54 }

 

你可能感兴趣的:(String)