LCS的路径输出问题(poj2250和poj2264)

poj2250和poj2264都是LCS问题的路径输出问题。其中,poj2250是裸题,poj2264稍微理解起来要拐个弯。

至于如何实现LCS的路劲输出,答案是DFS。回顾一下LCS的DP过程,每一步都三个选择(dp[i-1][j-1]、dp[i][j-1]、dp[i-1][j] ),根据情况判断一下具体走那条路。DFS过程刚好是个逆过程,递归前也有三个选择,根据情况选择递归的下一个状态。DFS(递归)天生就是干这个的。

理解LCS的递归过程,尤其是poj2264这个题,要清楚LCS的dp表,这个在《算法导论》有,可以结合这篇博客 看。


poj2250:

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;

string ta[105];
string tb[105];
string s;
int na,nb;

int dp[105][105];

void init()
{

    na=2,nb=1;

    while(cin>>s)
    {
        if(s=="#")
            break;
        ta[na]=s;
        na++;
    }
    while(cin>>s)
    {
        if(s=="#")
            break;
        tb[nb]=s;
        nb++;
    }
    na--;
    nb--;
}

void dfs(int i,int j)
{
    if(i==0||j==0)
        return;

    if(ta[i]==tb[j])
    {
        dfs(i-1,j-1);
        cout<<ta[i]<<" ";
        //放在dfs下面,才能在递归返回时打印;如果放在dfs上面的话,打出来的结果是倒序的
    }
    else if(dp[i][j-1]>dp[i-1][j])
        dfs(i,j-1);
    else
        dfs(i-1,j);
}

int main()
{

    while(cin>>s)
    {
       if(s=="#")
          break;
        ta[1]=s;
        init();
        for(int i=1; i<=na; i++)
        {
            for(int j=1; j<=nb; j++)
            {
                if(ta[i]==tb[j])
                    dp[i][j]=dp[i-1][j-1]+1;
                else
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }

        dfs(na,nb);
        cout<<endl;
   }
    return 0;
}

poj2264代码:

#include<cstdio>
#include<iostream>
#include<string>
#include<memory.h>
using namespace std;
int dp[105][105];

string a,b;
int la,lb;

void init(){  //初始化一下dp数组的边界
   int l=max(la,lb);
   for(int i=0;i<=l;i++){
    dp[i][0]=0;
    dp[0][i]=0;
   }
}

void dfs(int i,int j){
  if(i==0&&j==0)
    return;
   if(i==0){
    dfs(i,j-1);
    cout<<b[j-1];// j-1,这里 -1的原因是因为 a[]、b[]都是从下标0开始的,而dp[][]是从1开始的
  }
  else if(j==0){
    dfs(i-1,j);
    cout<<a[i-1//这里 -1的原因是因为 a[]、b[]都是从下标0开始的,而dp[][]是从1开始的
  }
  else if(a[i-1]==b[j-1]){ //这里 -1的原因是因为 a[]、b[]都是从下标0开始的,而dp[][]是从1开始的
        dfs(i-1,j-1);
        cout<<a[i-1];//这里 -1的原因是因为 a[]、b[]都是从下标0开始的,而dp[][]是从1开始的
    }

  else{
       if(dp[i-1][j]>dp[i][j-1]){
          dfs(i-1,j);
          cout<<a[i-1];//这里 -1的原因是因为 a[]、b[]都是从下标0开始的,而dp[][]是从1开始的
       }else{
           dfs(i,j-1);
           cout<<b[j-1];//这里 -1的原因是因为 a[]、b[]都是从下标0开始的,而dp[][]是从1开始的
       }
    }

}

int main(){
    while(cin>>a>>b){
        la=a.size();
        lb=b.size();
       init();
        for(int i=1;i<=la;i++){
            for(int j=1;j<=lb;j++){
                if(a[i-1]==b[j-1])
                    dp[i][j]=dp[i-1][j-1]+1;
                else{
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
      dfs(la,lb);
        cout<<endl;
    }
return 0;
}

猜你喜欢

转载自www.cnblogs.com/moderateisbest/p/9480351.html