hdu2476_区间dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2476

给出两个串s1和s2,一次只能将一个区间刷一次,问最少几次能让s1=s2

例如zzzzzfzzzzz,长度为11,我们就将下标看做0~10

先将0~10刷一次,变成aaaaaaaaaaa

1~9刷一次,abbbbbbbbba

2~8:abcccccccba

3~7:abcdddddcba

4~6:abcdeeedcab

5:abcdefedcab

这样就6次,变成了s2串了

第二个样例也一样

0

先将0~10刷一次,变成ccccccccccb

1~9刷一次,cdddddddddcb

2~8:cdcccccccdcb

3~7:cdcdddddcdcb

4~6:cdcdcccdcdcb

5:cdcdcdcdcdcb

最后竟串尾未处理的刷一次

就变成了串2cdcdcdcdcdcd

所以一共7次

 

思路:这种球区间最优解的,明显就是区间DP了- -,需要注意的是,要将1串变为2串,可以说,主要是看2串两个相同字符之间的区间

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <ctime>
 8 #include <queue>
 9 #include <list>
10 #include <set>
11 #include <map>
12 using namespace std;
13 #define INF 0x3f3f3f3f
14 typedef long long LL;
15 
16 char s1[110], s2[110];
17 int dp[110][110], res[110];
18 int main()
19 {
20     while(~scanf("%s %s", s1, s2))
21     {
22         int len = strlen(s1);
23         memset(dp, 0, sizeof(dp)); 
24         for(int j = 0; j < len; j++)
25         {
26             for(int i = j; i >= 0; i--)
27             {
28                 dp[i][j] = dp[i+1][j] + 1;
29                 for(int k = i+1; k <= j; k++)
30                     if(s2[i]==s2[k])
31                         dp[i][j] = min(dp[i][j], dp[i+1][k]+dp[k+1][j]);
32             }
33         }
34         for(int i = 0; i < len; i++)
35             res[i] = dp[0][i];
36         for(int i = 0; i < len; i++)
37         {
38             if(s1[i] == s2[i])
39             {
40                 if(i == 0)
41                     res[0] = 0;
42                 else
43                     res[i] = res[i-1];
44             }
45             else
46             {
47                 for(int j = 0; j < i; j++)
48                 {
49                     res[i] = min(res[i], res[j] + dp[j+1][i]);
50                 }
51             }
52         }
53         printf("%d\n", res[len-1]);
54     }
55     return 0;
56 }
View Code

 

posted @ 2016-09-27 21:23  海无泪  阅读(135)  评论(0编辑  收藏  举报