poj 1458 Common Sequence--动态规划

来源:互联网 发布:淘宝少发了一件怎么办 编辑:程序博客网 时间:2024/05/21 07:13

 问题描述:

给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列

  比如样例输入:

abcfbc  abccab 

样例输出

4

分析:1、确定状态: f[i][j]:表示前一个字符的前i位于后一个字符的前j位的最长公共子序列长度

        2、确定状态转移方程:

         if  x[i]==y[j]   长度为i的子序列和长度为j的最长公共子序列就是长度为i-1和长度为j-1的子序列中最长的序列加1,即f[i][j]=f[i-1][j-1]+1

      if  x[i]!=y[j]    第一个序列长度为i的子序列和第二个序列中长度为j的子序列的公共子序列中x[i]和y[j]不同时出现。

也就是说在x[0]~x[i]和y[0]~y[i]的最长公共子序列实际上与x[0]~x[i-1]和 y[0]~y[i]的最长公共子序列一样或者与x[0]~x[i]和 y[0]~y[i-1]的最长公共子序列一样
—     即:f[i][j]=max(f[i - 1][j] ,f[i][j - 1])  

      举例:


写程序时注意的问题:1.写了好几次都是wrong answer 造成的原因是因为:数组开小了,刚开始开的是200,后来扩大到999

      2.while(scanf("%s%s",x,y)!=EOF)注意x,y此时为字符串型

#include <iostream>#include <stdio.h>#include <algorithm>#include <string>using namespace std;int main(){    char  x[999],y[999];    int f[1000][1000];// 很容易出错    int m,n;    while(scanf("%s%s",x,y)!=EOF)    {        m=strlen(x);n=strlen(y);        for(int i=0;i<=m;i++)        {               f[i][0]=0;        }        for(int j=0;j<=n;j++)        {            f[0][j]=0;        }        for(int i=1;i<=m;i++)        {          for(int j=1;j<=n;j++)            {                if(x[i-1]==y[j-1])                     f[i][j]=f[i-1][j-1]+1;                else                     f[i][j]=max(f[i-1][j],f[i][j-1]);            }        }        printf("%d\n",f[m][n]);    }    return 0;}




0 0