题目链接: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 }