Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1524832
  • 博文数量: 399
  • 博客积分: 8508
  • 博客等级: 中将
  • 技术积分: 5302
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-14 09:28
个人简介

能力强的人善于解决问题,有智慧的人善于绕过问题。 区别很微妙,小心谨慎做后者。

文章分类

全部博文(399)

文章存档

2018年(3)

2017年(1)

2016年(1)

2015年(69)

2013年(14)

2012年(17)

2011年(12)

2010年(189)

2009年(93)

分类: LINUX

2010-01-19 14:22:09

Longest common subsequence问题:已知两序列,求这两个序列的最长公共子序列(不一定要连续)的长度。设二维数组dp[i][j]表示长度分别为i和j的序列 A和B的LCS的最大长度,有状态转移方程:A[i]=B[j]时,dp[i][j]=dp[i-1][j-1]+1;A[i]≠B[j]时,dp[i] [j]=max{dp[i-1][j],dp[i][j-1]}。
    通过观察发现,状态dp[i][j]只与当前行(dp[i][j-1])和上一行(dp[i-1][j],dp[i-1][j-1])的状态有关。这样, 我们可以设置2个一维数组c1[],c2[],其中c1[]保存上一行的状态信息,c2[]更新当前行的状态信息,更新完毕之后再将c2[]的状态信息复 制到c1[]中,循环结束后c1[length_B]就是所求LCS的最大长度,从而降低了空间需求。

#include
#include
int main()
{
        char s1[1000],s2[1000];         //输入两个字符串序列
        int  r[1000],s[1000];           //DP记录状态结果,采用滚动数组节省空间
        int  len1,len2,i,j;
        while(scanf("%s %s",s1,s2)!=EOF)
        {
                len1 = strlen(s1);
                len2 = strlen(s2);
                for(i=0;i                    r[i]=0;
                for(i=0;i                {
                        for(j=0;j                            if(s1[i]==s[j])     //如果序列对应字符相同
                                s[j+1]=r[j]+1;
                            else//如果序列对应字符不同,取长度较大的那一个
                                s[j+1]=r[j+1]>s[j]?r[j+1]:s[j];
                        for(j=1;j<=len2;++j)
                                r[j] = s[j];    //数组往后滚动
                }
                printf("%d\n",r[len2]);         //最大的字符串长度值是最后的元素值
        }
}

阅读(930) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~