LIS与LCS

最长公共子序列

一个给定序列的子序列是在该序列中删去若干个元素后得到的序列。子序列与子串不同,子序列在原序列中可以是不连续的,而子串必须是连续的。

最长公共子序列(longest common subsequence)问题:对给定的两个序列,找出他们的最长公共子序列。

L[i][j]={L[i1][j1](Xi=yj)max(L[i1][j],L[i][j1])(Xiyj)

int LCS(){
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=str1.length();i++){
        for(int j=1;j<=str2.length();j++){
            if(str1[i-1]==str2[j-1])
                dp[i][j]=dp[i-1][j-1]+1;
            else
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }
    return dp[str1.length()][str2.length()];
}

最长递增子序列

最长递增子序列(longest increasing subsequence)问题:给定一个长度为N的数组,找出一个最长的单调递增子序列。

方法一:用LCS求解


先对序列进行排序X‘,将X'和原序列X取最长公共子序列,即为最长递增子序列。

方法二:直接使用DP


DP[i]=max{DP[j],0}+1(0<ji1)

方法三:使用数组O(nlgn)


逐个处理原序列中的数,如果比辅助数组的最后一个数大,则在辅助数组的最后加入该数;否则替换掉原数组中的第一个大于该数的数字。

int LIS(){
    int len = 0;
    int d[maxn];
    d[1]=arr[1];
    for(int i=1;i<=n;i++){
        if(arr[i]>d[len])
            d[++len]=arr[i];
        else {
            //int j=lower_bound(d+1,d+1+len,arr[i]) - d;
            //或者二分查找
            int l=1,r=len+1;
            while(l<r){
                mid=(r+l)/2;
                if(d[mid]<arr[i])
                    l=mid+1;
                else r=mid+1;
            }
            j=l;
            d[j]=arr[i];
        }     
    }
    return len;
}
posted @   Aliancn  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示