poj2250-打印单一LCS路径。

来源:互联网 发布:竹炭和活性炭知乎 编辑:程序博客网 时间:2024/04/30 23:26

题目连接

题意:就是一个最长公共子序列。并打印其路径。

分析:最长公共子序列还不难,注意是打印它的一条路径。我们知道是用二维数组dp来保存它的匹配数。一旦有匹配的它就修改后面的值,保证了

如何一个状态当前的dp数据中是最大的值。看一张经典的图:


显示了路径的回溯。帮助我们能找到匹配的的过程。

为了记录它转移的方向。我们需要用辅助数组map来记录它是有那个状态转移而来的。可以用递归来实现。

代码如下:

#include<cstdio>#include<cstring>//using namespace std;int dp[105][105],map[105][105];char s[100][35],t[100][35];void LCS(int a,int b){for(int i=1;i<=a;i++) for(int j=1;j<=b;j++)  if(strcmp(s[i-1],t[j-1])==0)  {    dp[i][j]=dp[i-1][j-1]+1;    map[i][j]=1;  }  else{    if(dp[i-1][j]>=dp[i][j-1]) {map[i][j]=2;dp[i][j]=dp[i-1][j];}else{map[i][j]=3;dp[i][j]=dp[i][j-1];}  }}void path(int a,int b)  //打印LCS路径{      if(a==0||b==0) return;    if(map[a][b]==1){          path(a-1,b-1);          printf("%s ",s[a-1]);      }      else if(map[a][b]==2)         path(a-1,b);      else         path(a,b-1);  }  int main(){int i,j,len1,len2;while(scanf("%s",s[0])!=EOF){  //memset(dp,0,sizeof(dp));  for(len1=1;;len1++)  {scanf("%s",s[len1]); if(strcmp(s[len1],"#")==0) break;  }  for(len2=0;;len2++)  {      scanf("%s",t[len2]);      if(strcmp(t[len2],"#")==0) break;          }          LCS(len1,len2);  path(len1,len2);  printf("\n");}   return 0;     }


原创粉丝点击