poj2250-打印单一LCS路径。

前端之家收集整理的这篇文章主要介绍了poj2250-打印单一LCS路径。前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

题目连接

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

分析:最长公共子序列还不难,注意是打印它的一条路径。我们知道是用二维数组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,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;     
}

猜你在找的设计模式相关文章