Trip

Trip

Given a sequence of length n \ (\ {a_i \} \) , a sequence of length m \ (\ {B_i \} \) , lcs sequences find their different lexicographical order output, \ (n, m \ Leq 80 \) , LCS no more than 1000 characters for the 26 lowercase letters.

solution

Note that, according to the traditional idea of recursive transfer + + violence program merge sort, time complexity \ (O (80. 3 ^ \ Times 1000) = O (512 000 000) = O (5.12 \ ^ 10 Times. 8) \) , bound timeout, the data range and small, dfs considered, and the results used to optimize dfs recursion.

In order to make the results of recursive \ (F [i] [j] \) represents a before sequence length i, j longest sequence length b lcs former can work, must be searched forward from the back, if the current state to provide plus the lcs lcs not have been identified as the optimal solution, you can prune addition, in order to quickly identify the same characters, we maintain \ (fa [i] [j ] \) represents a sequence of characters in the i \ (1 \ sim j \) position of the rearmost, fb Similarly, there is not difficult

\ [Four [c] [j] = \ Max (four [c] [j-1], j (a [j] == to + 96)) \]

So the maintenance of these two things, in order to dfs pruning, you can have a very high efficiency, and will not tle up.

Reference Code:

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#define il inline
#define ri register
using namespace std;
string a,b,ans[2050];
int dp[101][101],fa[101][101],
    fb[101][101],tot,len;
il int max(int,int);
void dfs(int,int,string),work();
int main(){
    int lsy;cin>>lsy;
    while(lsy--)work(),putchar('\n');
    return 0;
}
void work(){
    cin>>a>>b,tot&=0;
    for(int i(1),j;i<=a.size();++i)
        for(j=1;j<=b.size();++j){
            dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
            if(a[i-1]==b[j-1])dp[i][j]=max(dp[i-1][j-1]+1,dp[i][j]);
        }
    for(int i(1),j;i<=26;++i){
        for(j=1;j<=a.size();++j)
            if(a[j-1]==i+96)fa[i][j]=j;
            else fa[i][j]=fa[i][j-1];
        for(j=1;j<=b.size();++j)
            if(b[j-1]==i+96)fb[i][j]=j;
            else fb[i][j]=fb[i][j-1];
    }len=dp[a.size()][b.size()];
    dfs(a.size(),b.size(),""),sort(ans+1,ans+tot+1);
    for(int i(1);i<=tot;++i)cout<<ans[i]<<endl;
}
void dfs(int a,int b,string s){
    if(a<0||b<0)return;
    if(s.size()==len)return(void)(ans[++tot]=s);
    for(int i(1);i<=26;++i)
        if(dp[fa[i][a]][fb[i][b]]+s.size()==len)
            dfs(fa[i][a]-1,fb[i][b]-1,(char)(i+96)+s);
}
il int max(int a,int b){
    return a>b?a:b;
}

Guess you like

Origin www.cnblogs.com/a1b3c7d9/p/10995765.html