POJ 1159 Palindrome

这一题的思路就是先求出原序列与原序列的逆序列的最大公共子序列的长度,然后用原序列的长度减去即可。至于为什么这样做还请高手指点。。。因为题目中的数据量比较大,开5000*5000的数组会MLT,所以考虑用滚动数组来做。。。状态f[i][j]表示检测的Ai与Bj时的最大公共子序列的长度,状态转移方程为:f[i][j] = max{f[i - 1][j], f[i][j - 1]} + 1。。。

AC code:

View Code
 1 #include <iostream>
2 #define MAX 5001
3 using namespace std;
4 int maxlen[2][MAX];
5 char s1[MAX], s2[MAX];
6 int n;
7 int main()
8 {
9 while(scanf("%d", &n) != EOF)
10 {
11 int i,j;
12 getchar();
13 for(i = 1; i <= n; i++)
14 {
15 scanf("%c", &s1[i]);
16 s2[n - i + 1] = s1[i];
17 }
18 s1[n + 1] = '\0';
19 s2[n + 1] = '\0';
20 memset(maxlen, 0, sizeof(maxlen));
21 int e = 0;//这里用到了滚动数组
22 for(i = 1; i <= n; i++)
23 {
24 e = 1 - e;
25 for(j = 1; j <= n; j++)
26 {
27 if(s1[i] == s2[j])
28 maxlen[e][j] = maxlen[1 - e][j - 1] + 1;
29 else
30 {
31 int len1 = maxlen[e][j - 1];
32 int len2 = maxlen[1 - e][j];
33 maxlen[e][j] = len1 > len2 ? len1 : len2;
34 }
35 }
36 }
37 printf("%d\n",n - maxlen[e][n]);
38 }
39 return 0;
40 }



posted @ 2012-03-06 16:14  背着超人飞  阅读(140)  评论(0)    收藏  举报