zoukankan      html  css  js  c++  java
  • LuoGu1439 LCS模板

     

    作为特别特别经典的一类序列DP,相信大家都应该了解LCS吧!

    那么最基本的n方做法就只简述一下:

    设f[i][j]表示第一个序列匹配到了第i位,第二个匹配到了第j位;

    转移

    f[i][j]=max (f[i-1][j], f[i][j-1]);
    if (a[i]==b[j]) f[i][j]=max (f[i][j], f[i-1][j-1]+1);

    然后 n方此处不够优秀

    对于两个都是1-n的一个排列的求LCS的问题(LuoGu P1439 模板)是可以nlogn解决的

    考虑怎么优化 。

    实际上我们可以发现,如果存在一组公共子序列,那么这就意味着他们在原序列中,对应位置的 相对大小 也是一定的(因为都是1-n)。

    所以我们把其中一个序列的每一个值对应上其位置,另一个序列对应的转换,这样就只要求LIS就行了

    例如 3 2 1 4 5 和 1 2 3 4 5:

    把第一个先对应上其位置(用a数组),

    a[3]=1, a[2]=2, a[1]=3, a[4]=4, a[5]=5

    另外一个再对应一下,则得到3 2 1 4 5

    这样再把1 2 3 4 5 和 3 2 1 4 5 求LIS 即 2 4 5,对应到原序列分别为 2 4 5就是他们的LCS。

    这样问题就解决了。

    Update:

    SP33TRIP

    题意:LCS方案输出。

    思路:求出LCS长度后,预处理好前i个子母中,字母j出现的最后位置。

    然后DFS,依次枚举每一位填什么字母,注意好条件的限制就可以了。

    void dfs (int x,int y,int num,string ss) {
        if (num==0) {ans.insert(ss);return;}
        for (RG int i=1;i<=26;++i) {
            if (la[x][i]>=num&&lb[y][i]>=num&&f[la[x][i]][lb[y][i]]==num) 
                dfs(la[x][i]-1,lb[y][i]-1,num-1,(char)(i+'a'-1)+ss);
        }
    }
  • 相关阅读:
    Java模拟ATM运行过程(第一版)
    双色Hanoi塔问题及判断指令
    一点编程风格
    游戏程序员养成计划
    OGRE编译
    Python学习收藏
    case 语句注意
    [c、c++]宏中"#"和"##"的用法(zz)
    网络代码平台tortoise svn+google code
    使用delegate进行解耦
  • 原文地址:https://www.cnblogs.com/Bhllx/p/9806864.html
Copyright © 2011-2022 走看看