# 动态规划——最长公共子序列（LCS）

-----Edit by ZhuSenlin HDU

1） 确定LCS最优子结构。设为X和Y的任意一个LCS，则

2） 寻找递归解

3） 计算长度

template <class T>
void CreateTable(T**& pTable, int nH, int nW)
{
DeleteTable(pTable,nH);
pTable = new T* [nH];
for(int i = 0; i < nH; i++)	{
pTable[i] = new T[nW];
memset(pTable[i],0,nW*sizeof(T));
}
}

template <class T>
void DeleteTable(T**& pTable, int nH)
{
if(!pTable)
return;
for(int i = 0; i < nH; i++)
if(pTable[i])
delete pTable[i];
delete pTable;
}

int LengthLCS(const char* pStrA, const char* pStrB, int**& pTable, char**& pPath)
{
int nLengthA = strlen(pStrA);
int nLengthB = strlen(pStrB);
for(int i = 1; i<= nLengthA; i++){
for(int j = 1; j <= nLengthB; j++) {
if(pStrA[i-1] == pStrB[j-1]) {
pTable[i][j] = pTable[i-1][j-1]+1;
pPath[i][j] = 'x';
}
else if(pTable[i-1][j] < pTable[i][j-1]){
pTable[i][j] = pTable[i][j-1];
pPath[i][j] = 'l';
}
else {
pTable[i][j] = pTable[i-1][j];
pPath[i][j] = 'u';
}
}
}
return pTable[nLengthA][nLengthB];
}

void PrintLCS(char** pPath, const char* pStrA,int nLengthA, int nLengthB)
{
if(nLengthA == 0 || nLengthB == 0)
return;
if(pPath[nLengthA][nLengthB] == 'x') {
PrintLCS(pPath, pStrA, nLengthA-1, nLengthB-1);
cout << pStrA[nLengthA-1] << " ";
}
else if(pPath[nLengthA][nLengthB] == 'l')
PrintLCS(pPath,pStrA,nLengthA,nLengthB-1);
else
PrintLCS(pPath,pStrA,nLengthA-1,nLengthB);
}


int main()
{
const char* pStrA = "abcbdab";
const char* pStrB = "bdcaba";
int** pTable = NULL;
char** pPath = NULL;
int nLengthA = strlen(pStrA);
int nLengthB = strlen(pStrB);
CreateTable(pTable,nLengthA+1,nLengthB+1);
CreateTable(pPath,nLengthA+1,nLengthB+1);

cout << LengthLCS(pStrA,pStrB,pTable,pPath) << endl;
PrintLCS(pPath,pStrA,strlen(pStrA),strlen(pStrB));
cout << endl;

DeleteTable(pTable,strlen(pStrA)+1);
DeleteTable(pPath,strlen(pStrA)+1);
return 0;
}

• 本文已收录于以下专栏：

举报原因： 您举报文章：动态规划——最长公共子序列（LCS） 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)