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.
|
|
|
Sample Input abcfbc abfcabprogramming contest abcd mnp
|
Sample Output 420 |
dp题目,初学dp所以都不是很清楚,看了好多资料才马马虎虎AC了,我觉得最引发头绪的就是以下几句话了:
序列X=<x1,x2,...,xm>,Y=<y1,y2,...,yn>.假设它们的LCS是Z=<z1,z2,...,zk>。那么可以知道的就是下面的三个结论:
1.如果xm=yn的话,我们可以得知xm=yn=zk,且Zk-1是Xm-1,Yn-1的一个LCS;
2.如果xm不等于yn的话,如果zk不等于xm的话,那么Zk是Xm-1,Yn的一个LCS;
3.如果xm不等于yn的话,如果zk不等于yn的话,那么Zk是Xm,Yn-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;
}
}