HDU Common Subsequence 解题报告

Problem Description

A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, ..., ik> of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.

 


 

 

 

Sample Input

abcfbc abfcabprogramming contest abcd mnp

 


 

Sample Output

420

 

dp题目,初学dp所以都不是很清楚,看了好多资料才马马虎虎AC了,我觉得最引发头绪的就是以下几句话了:

序列X=<x1,x2,...,xm>,Y=<y1,y2,...,yn>.假设它们的LCSZ=<z1,z2,...,zk>。那么可以知道的就是下面的三个结论:

1.如果xm=yn的话,我们可以得知xm=yn=zk,Zk-1Xm-1Yn-1的一个LCS

2.如果xm不等于yn的话,如果zk不等于xm的话,那么ZkXm-1Yn的一个LCS;

3.如果xm不等于yn的话,如果zk不等于yn的话,那么ZkXmYn-1的一个LCS

由此可以弄个二维数组dp[i][j],其中i是X序列字符个数,j是Y序列字符个数,dp[i][j]表示当前状态下的LCS值,

当Xi==Yj时,dp[i][j]=dp[i-1][j-1]+1;(对应于上面第一个如果的情况)

当Xi!=Yj时,dp[i][j]=max{dp[i-1][j],dp[i][j-1]},就是对应于上面2,3情况,找大的那个作为当前的状态;

附上个不错的解释http://blog.chinaunix.net/uid-26548237-id-3374211.html

 

贴代码:

#include<iostream>
#include<string>
using namespace std;
int dp[1005][1005];//全局变量已经全部刷0了,没必要又去赋值0

void main()
{
 string X,Y;
 int i,j,lenX,lenY;
 while(cin>>X>>Y)
 {
  lenX=X.length();
  lenY=Y.length();
  for(i=1;i<=lenX;i++)
  {
   for(j=1;j<=lenY;j++)
   {
    if(X[i-1]==Y[j-1])
     dp[i][j]=dp[i-1][j-1]+1;
    else
    {
     if(dp[i-1][j]>dp[i][j-1])
      dp[i][j]=dp[i-1][j];
     else
      dp[i][j]=dp[i][j-1];
    }
   }
  }
  cout<<dp[lenX][lenY]<<endl;
 }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值