当前位置: 首页 > news >正文

最长公共子序列(动态规划法+优化)

最长公共子序列(LCS)(1)

题目描述

给出1-n的两个排列P1和P2,求它们的最长公共子序列。

输入

第一行是一个数n;(n是5~1000之间的整数)数据范围小,可以用二维数组dp
接下来两行,每行为n个数,为自然数1-n的一个排列(1-n的排列每行的数据都是1-n之间的数,但顺序可能不同,比如1-5的排列可以是:1 2 3 4 5,也可以是2 5 4 3 1)。

输出

一个整数,即最长公共子序列的长度。

样例输入 
5 
3 2 1 4 5
1 2 3 4 5
样例输出 
3
import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int n=scan.nextInt();
        int []a=new int[n+1];
        int []b=new int[n+1];
        int [][] dp=new int[n+1][n+1];
        for(int i=1;i<=n;i++){
            a[i]=scan.nextInt();
        }
        for(int i=1;i<=n;i++){
            b[i]=scan.nextInt();
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(a[i]==b[j]){
                    dp[i][j]=dp[i-1][j-1]+1;
                }else{
                    dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        System.out.println(dp[n][n]);
    }
}

 最长公共子序列(LCS)(2)

题目描述

给出1-n的两个排列P1和P2,求它们的最长公共子序列。
和最长公共子序列(LCS)(1)问题不同的是,本题的n在5-100000之间。数据范围大,要用映射的做法把问题转化为求最长递增子序列的长度

输入

第一行是一个数n;(n是5-100000之间的整数)
接下来两行,每行为n个数,为自然数1-n的一个排列(1-n的排列每行的数据都是1-n之间的数,但顺序可能不同,比如1-5的排列可以是:1 2 3 4 5,也可以是2 5 4 3 1)。

输出

一个整数,即最长公共子序列的长度。

样例输入 
5 
3 2 1 4 5
1 2 3 4 5
样例输出 
3
提示

对于50%的数据,n≤1000
对于100%的数据,n≤100000

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int n=scan.nextInt();
        int[] p1=new int[n];
        int[] p2=new int[n];
        for(int i=0;i<n;i++){
            p1[i]=scan.nextInt();
        }
        for(int i=0;i<n;i++){
            p2[i]=scan.nextInt();
        }
        //映射
        int[] pos=new int[n+1];
        for(int i=0;i<n;i++){
            pos[p2[i]]=i;
        }
        int[] nums=new int[n+1]; //[2,1,0,3,4]
        for(int i=0;i<n;i++){
            nums[i]=pos[p1[i]];
        }
        //求nums的最长递增子序列
        int[] tails=new int[n];
        int len=0;
        for(int i=0;i<n;i++){
            int num=nums[i];
            int left=0;
            int right=len-1;
            int insertpos=len;
            while (left<=right){
                int mid=left+(right-left)/2;
                if(tails[mid]<num){
                    left=mid+1;
                }else{
                    insertpos=mid;
                    right=mid-1;
                }
            }
            tails[insertpos]=num;
            if(insertpos==len){
                len++;
            }
        }
        System.out.println(len);
 
    }
}

相关文章:

  • NL2SQL 优化之 Schema 编写标准
  • 单词翻转(信息学奥赛一本通-1144)
  • AI视觉测试工具实战评测:以Applitools为例的技术解析与行业应用
  • CoreData 调试警告:多个 NSEntityDescriptions 声明冲突的解决
  • JSON 数据详解
  • 【再读】R1-Onevision通过跨模态形式化为复杂多模态推理任务提供了系统性解决方案
  • 盘库吧--搜索
  • 开源模型中的 Function Call 方案深度剖析
  • 【Linux系统】进程地址空间详解
  • 代码随想录算法训练营第五十九天| 图论05
  • 【MySQL】MySQL如何存储数据?
  • 计算机网络-1-1计算机网络体系结构
  • 清晰易懂的Java8安装教程
  • Deepseek API+Python测试用例一键生成与导出-V1.0.2【实现需求文档图片识别与用例生成自动化】
  • 可视化图解算法:判断链表中是否有环(环形链表)
  • JVM 垃圾回收器分类及其特点详解
  • TypeScript语言的计算机视觉
  • 前端性能优化回答思路
  • 【自学笔记】Redis基础知识点总览-持续更新
  • 移除元素(快慢指针)
  • 上海明天短暂恢复晴热最高32℃,一大波雨水在候场
  • 大学2025丨北大教授陈平原:当卷不过AI时,何处是归途
  • 台湾关闭最后的核电,岛内担忧“非核家园”缺电、涨电价困局难解
  • 首次带人形机器人走科技节红毯,傅利叶顾捷:没太多包袱,很多事都能从零开始
  • 贵州省委军民融合发展委员会办公室副主任李刚接受审查调查
  • 经济日报评外卖平台被约谈:行业竞争不能背离服务本质