A Za, A Za, Fighting...

坚信:勤能补拙

PKU 1159 Palindrome

问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1159

思路:
看完题目,完全不知道该怎么做
参考discuss,发现原来DP这么这么地强大,自己那是相当菜
设ch[1]..ch[n]表示字符串1至n位,i为左游标,j为右游标 ,则i从n递减,j从i开始递增。
min[i][j]表示i和j之间至少需要插入多少个字符才能对称,初始置全0 ,我们最终需要得到的值是min[1][n].
则
if(ch[i]==ch[j])                                    //如果两个游标所指字符相同,向中间缩小范围
    min[i][j]=min[i+1][j-1];
else
    min[i][j] = 1 +(min[i+1][j]和min[i][j-1]中的较小值);     //如果不同,典型的状态转换方程
额,状态方程看明白了,结果发现代码居然不知道怎么写...那个汗哪...
原因是没有发现当i>j时,min[i][j] = 0

代码(记忆化搜索):
 1 /* Time: 1594MS */
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #define MAX_LEN 5001
 6 char str[MAX_LEN+1];
 7 int len;
 8 short memory[MAX_LEN][MAX_LEN];
 9 
10 /*
11  * f[i][j] represent the minimal insert for str[i..j]
12  *
13  * f[i][j] = f[i+1][j-1], if str[i]==str[j], otherwise
14  * f[i][j] = min(f[i+1][j], f[i][j-1]) + 1
15  */
16 int
17 func(int i, int j)
18 {
19     int a, b;
20     if(i >= j)
21         return 0;
22     if(memory[i][j])
23         return memory[i][j];
24     if(str[i] == str[j])
25         memory[i][j] = func(i+1, j-1);
26     else {
27         a = func(i+1, j);
28         b = func(i, j-1);
29         memory[i][j] = a<? a+1 : b+1;
30     }
31     return memory[i][j];
32 }
33 
34 int
35 main(int argc, char **argv)
36 {
37     while(scanf("%d"&len) != EOF) {
38         memset(memory, 0sizeof(memory));
39         scanf("%s", str+1);
40         printf("%d\n", func(1, len));
41     }
42 }

代码(dp):
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define MAX_LEN 5001
 5 char str[MAX_LEN];
 6 int len;
 7 short table[MAX_LEN][MAX_LEN];
 8 
 9 short
10 dp()
11 {
12     int i, j;
13     /* if i>j, then table[i][j] = 0 */
14     for(i=len-1; i>=1; i--) {
15         for(j=i; j<=len; j++) {
16             if(str[i] == str[j])
17                 table[i][j] = table[i+1][j-1];
18             else
19                 table[i][j] = table[i+1][j]<table[i][j-1? table[i+1][j]+1 : table[i][j-1]+1;
20         }
21     }
22     return table[1][len];
23 }
24 
25 int
26 main(int argc, char **argv)
27 {
28     while(scanf("%d"&len) != EOF) {
29         memset(table, 0sizeof(table));
30         scanf("%s", str+1);
31         printf("%d\n", dp());
32     }
33 }

posted on 2010-08-12 19:47 simplyzhao 阅读(141) 评论(0)  编辑 收藏 引用 所属分类: C_动态规划


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2010年8月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜