//目录

Uva 4394 字符串刷子

题目链接:https://vjudge.net/contest/164840#problem/A

题意:一个字符串刷子,每次可以将一段连续的字符串变成一种颜色,给两个字符串,最少通过几次可以将第一个字符串转换为第二个字符串;

 

分析:

首先假设第一个字符串和第二个字符串全部不相同,那么怎么刷成第二个字符串?

dp[i][j] 就是将完全不同的字符串刷成第二个的最少步数,可以这样考虑,当中间一个字符串和首字符串相同,

可能这样刷两次会比较好,当然这两个状态已经算出来了;

 

回到原题;

当两个字符串两个位置相同 ans[i] = ans[i-1] ,这个字符串可以不用刷;

不同,最坏情况就是 dp[1][i];同理,也可以找出两个部分来有可能更优;

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int maxn = 100 + 5;
 6 char str1[maxn];
 7 char str2[maxn];
 8 int dp[maxn][maxn];
 9 int ans[maxn];
10 
11 int main()
12 {
13     while(~scanf("%s%s",str1+1,str2+1)) {
14 
15         int len = strlen(str1+1);
16 
17         memset(dp,0,sizeof(dp));
18 
19         for(int i=1;i<=len;i++)
20             dp[i][i] = 1;
21 
22         for(int i=2;i<=len;i++) {
23             for(int j=1;j+i-1<=len;j++) {
24                 int r = i+j-1;
25                 dp[j][r] = dp[j+1][r] + 1;  //不能是 dp[j][r-1] + 1;这个还没算出来
26                 for(int k=j+1;k<=r;k++) {
27                     if(str2[j]==str2[k])
28                         dp[j][r] = min(dp[j][r],dp[j+1][k]+dp[k+1][r]);
29                 }
30             }
31         }
32 
33         memset(ans,0,sizeof(ans));
34 
35         if(str1[1] == str2[1])
36             ans[1] = 0;
37         else ans[1] = 1;
38         for(int i=2;i<=len;i++) {
39             if(str1[i]==str2[i])
40                 ans[i] = ans[i-1];
41             else {
42                 ans[i] = dp[1][i];
43                 for(int j=1;j<i;j++) {
44 
45                     ans[i] = min(ans[i],ans[j]+dp[j+1][i]);
46                 }
47             }
48         }
49         printf("%d\n",ans[len]);
50 
51     }
52     return 0;
53 }
View Code

 

posted @ 2017-05-22 21:26  小草的大树梦  阅读(246)  评论(0编辑  收藏  举报