dp最长公共子串LCS

http://acm.hdu.edu.cn/showproblem.php?pid=1159

这题可用递归解出

(1)递归方法求最长公共子序列的长度

    1)设有字符串a[0...n],b[0...m],下面就是递推公式。

             当数组a和b对应位置字符相同时,则直接求解下一个位置;当不同时取两种情况中的较大数值。

    

#include<stdio.h>//会超时 
#include<string.h>
char a[100000],b[100000];
int lena,lenb;
int LCS(int i,int j)
{
     if(i>=lena || j>=lenb)
        return 0;
    if(a[i]==b[j])
        return 1+LCS(i+1,j+1);
    else
        return LCS(i+1,j)>LCS(i,j+1)? LCS(i+1,j):LCS(i,j+1);
}
int main()
{
    while(scanf("%s %s",a,b)!=EOF)
    {
       lena=strlen(a);
       lenb=strlen(b);
       printf("%d\n",LCS(0,0));
    }
    return 0;
}
View Code

但是这样子的方法会超时

接下来就是动态规划

(2)动态规划求最长公共子序列的长度

    动态规划采用二维数组来标识中间计算结果,避免重复的计算来提高效率。

    1)最长公共子序列的长度的动态规划方程

    设有字符串a[0...n],b[0...m],下面就是递推公式。字符串a对应的是二维数组num的行,字符串b对应的是二维数组num的列。

    

 

#include<stdio.h>
#include<string.h> 
int ans[1000][1000];
int max(int a,int b)
{
    return a>b?a:b;
} 
int main()
{
    int i,j,lena,lenb;
    char a[10000],b[10000];
    while(scanf("%s %s",a,b)!=EOF)
    {
       lena=strlen(a);
       lenb=strlen(b);
       for(i=0;i<=lena;i++)
         for(j=0;j<=lenb;j++)
           ans[i][j]=0;//初始化为0 
       for(i=1;i<=lena;i++)
         for(j=1;j<=lenb;j++)
         {
             if(a[i-1]==b[j-1])//如果都相等,两个指针都前移并将该处的子串长度加一 
             ans[i][j]=1+ans[i-1][j-1];
             else ans[i][j]=max(ans[i][j-1],ans[i-1][j]);//否则保留两个子串前个阶段最大的那个 
         }
       printf("%d\n",ans[lena][lenb]);
    }
    return 0;
}
View Code

还写出了一个错误的代码。。。

#include<stdio.h>
#include<string.h> 
int ans[1000][1000];
int max(int a,int b)
{
    return a>b?a:b;
} 
int main()
{
    int i,j,lena,lenb;
    char a[10000],b[10000];
    while(scanf("%s %s",a,b)!=EOF)
    {
       lena=strlen(a);
       lenb=strlen(b);
       for(i=0;i<lena;i++)
         for(j=0;j<lenb;j++)
           ans[i][j]=0;//
       for(i=0;i<lena;i++)
         for(j=0;j<lenb;j++)//
         {
             if(a[i]==b[j])
             ans[i+1][j+1]=1+ans[i][j];//
             else ans[i+1][j+1]=max(ans[i][j+1],ans[i+1][j]);//这里错误,此时二者还都是未知 
         }
       printf("%d\n",ans[i][j]);
    }
    return 0;
}
View Code

 

posted @ 2013-08-06 17:09  执着追求的IT小小鸟  阅读(184)  评论(0编辑  收藏  举报