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 }

 

posted @ 2013-11-30 14:29  芷水  阅读(197)  评论(0编辑  收藏  举报