(动态规划)1042最长公共子序列问题

来源:互联网 发布:spark快速大数据分析 编辑:程序博客网 时间:2024/06/17 11:57
1042 题目描述:

Find a longest common subsequence of two strings.

QQ截图20120301122229.jpg

输入:

First and second line of each input case contain two strings of lowercase character a…z. There are no spaces before, inside or after the strings. Lengths of strings do not exceed 100.

输出:

For each case, output k – the length of a longest common subsequence in one line.

样例输入:
abcdcxbydz
样例输出:
2
这是一个典型的动态规划问题,不需要子序列连续,每一个状态只与前面一个状态有关

引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。

问题的递归式写成:

recursive formula

最后代码如下:
#include <stdio.h>#include <string.h>#define MAX 110int max(int a,int b){return (a>=b)?a:b;}int lcs(char x[],char y[]){int ans=0;int a[MAX][MAX];int len1=strlen(x);int len2=strlen(y);int i,j;for(i=0;i<len1;i++){for(j=0;j<len2;j++){if(x[i]==y[j]){(i==0||j==0)?a[i][j]=1:a[i][j]=a[i-1][j-1]+1;}else{  if(i==0&&j==0)      a[i][j]=0;  else if(i==0)       a[i][j]=a[i][j-1];    else if(j==0)   a[i][j]=a[i-1][j];  else       a[i][j]=max(a[i][j-1],a[i-1][j]);               }  if (a[i][j] > ans)                    {                     ans = a[i][j];                   }     }}return ans;}int main(){    char x[MAX],y[MAX];    int ans;while(scanf("%s%s",x,y)!=EOF)        {               ans=lcs(x,y);   printf("%d\n",ans);        }        return 0;}
原创粉丝点击