最长公共子序列 (LCS) 学习小记 Hdu 1159 + Poj 2250 (LCS路径打印)

来源:互联网 发布:淘宝短信怎么退订 编辑:程序博客网 时间:2024/05/17 17:17

其实这东西刚进实验室的时候就学过,当时还不知道dp是啥……记得当时滚动数组优化看了一晚上没学会。。。

现在看来就是一个很基础的dp……


最长公共子序列(LCS) | 勇幸|Thinking
http://www.ahathinking.com/archives/115.html


Hdu 1159

#include <cstdio>#include <cstring>#define max(x,y) ((x)>(y)?(x):(y))/* 滚动数组 */int dp[2][1005];  /* 存储LCS长度 */char str[1005],ch[1005];int main (){while (~scanf("%s%s",str,ch)){int lenstr=strlen(str);int lench=strlen(ch);memset(dp,0,sizeof(dp));int k;for (int i=1;i<=lenstr;i++){k=i&1;for (int j=1;j<=lench;j++)if (str[i-1] == ch[j-1])dp[k][j]=dp[k^1][j-1]+1;elsedp[k][j]=max(dp[k][j-1],dp[k^1][j]);}printf("%d\n",dp[k][lench]);}return 0;}/*asdlkfjlksdsldkfjlksjdf9*//*Discuss里看到的。。。。::.--.-.:::( (    ):::::  东边日出西边雨 (_,  \ ) ,_)::  道是无晴却有情       |:::-'--`--:::::::: ~~|     ,       \ _ /::::::::::::::::::: ,|`-._/|   -==  (_)  ==-::::::::^^::::::::.' |   /||\      /   \::::::^^::::::::.'   | ./ ||`\       |:::::::::::::::/ `-. |/._ ||  \::::::::::::::|      ||   ||   \ ~~=~_~^~ =~ \~~~~~~~'~~~~'~~~~/~~`` ~=~^~~^^~~-=~^~ ^ `--------------'~^~=~^~_~^=~^~*/

Poj 2250

#include <cstdio>#include <cstring>int dir[102][102],d[102][102];char a[102][31],b[102][31];void LCS (int na,int nb){int i,j;for (i=1;i<=na;i++)for (j=1;j<=nb;j++)if (strcmp(a[i-1],b[j-1]) == 0)       //找到,向右下{d[i][j]=d[i-1][j-1]+1;dir[i][j]=1;}else if (d[i-1][j] > d[i][j-1])       //未找到,向下{d[i][j]=d[i-1][j];dir[i][j]=2;}else                                  //未找到,向右{d[i][j]=d[i][j-1];dir[i][j]=3;}}void Output (int i,int j){if (i == 0 || j == 0)return;if (dir[i][j] == 1){Output(i-1,j-1);printf("%s ",a[i-1]);}if (dir[i][j] == 2)Output(i-1,j);if (dir[i][j] == 3)Output(i,j-1);}int main (){#ifdef ONLINE_JUDGE  #elsefreopen("read.txt","r",stdin);#endifwhile (~scanf("%s",a[0])){if (a[0][0] == '#')break;memset(dir,0,sizeof(dir));memset(d,0,sizeof(d));int i=1,j=0;while (scanf("%s",a[i])){if (a[i][0] == '#')break;i++;}while (scanf("%s",b[j])){if (b[j][0] == '#')break;j++;}LCS(i,j);Output(i,j);printf("\n");}return 0;}