POJ1934 Trip problem solution

LCS template, but want to output specific programs, which is a cancer.
Magic pretreatment: fa[i][j]indicates \ (A \) before the string \ (I \) characters in the alphabet of \ (J \) position occurs last letter of fb[i][j]the same reason.
So that we can find a path recursively, for the same position of two letters pointer recursively down, otherwise pretreated with an array of recursive enumeration same position again.
Also according to the dictionary order output, open seton the line.

#include <bits/stdc++.h>
using namespace std;

const int N=85;
char a[N],b[N],s[N];
int ans,f[N][N],fa[N][26],fb[N][26];
set<string> ss;

void getPath(int n,int m,int len)
{
    if(!len)
    {
        string t;
        for(int i=1;i<=ans;++i) t+=s[i];
        ss.insert(t); return;
    }
    if(!n||!m) return;
    if(a[n]==b[m])
    {
        s[len]=a[n];
        getPath(n-1,m-1,len-1);
    }
    else
    {
        for(int i=0;i<26;++i)
            if(f[fa[n][i]][fb[m][i]]==len)
                getPath(fa[n][i],fb[m][i],len);
    }
}

int main()
{
    scanf("%s %s",a+1,b+1);
    int n=strlen(a+1),m=strlen(b+1);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            if(a[i]==b[j]) f[i][j]=f[i-1][j-1]+1;
            else f[i][j]=max(f[i-1][j],f[i][j-1]);
    ans=f[n][m];
    for(int i=1;i<=n;++i)
        for(int j=0;j<26;++j)
            fa[i][j]=a[i]!='a'+j?fa[i-1][j]:i;
    for(int i=1;i<=m;++i)
        for(int j=0;j<26;++j)
            fb[i][j]=b[i]!='a'+j?fb[i-1][j]:i;
    getPath(n,m,ans);
    for(string str : ss) cout << str << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/wzzyr24/p/12301435.html