• POJ1934 Trip 题解


    LCS 模板,但要输出具体方案,这就很毒瘤了。
    神奇的预处理:fa[i][j]表示在 (a) 串的前 (i) 个字符中,字母表第 (j) 个字母最晚出现的位置,fb[i][j]同理。
    这样我们便可以递归找路径,对于两指针的位置的字母相同就向下递归,否则用预处理数组枚举相同位置再递归。
    还要按字典序输出,开个set就行了。

    #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;
    }
    
  • 相关阅读:
    Android中ProgressBar显示小数的方法
    Android屏幕适配-安卓切图
    android -services
    Java 位移运算符
    异常、集合、数据结构
    常用类
    编码
    String类
    Android-1
    ButterKnife注解式绑定控件
  • 原文地址:https://www.cnblogs.com/wzzyr24/p/12301435.html
Copyright © 2020-2023  润新知