首页 > 其他分享 >P1439 【模板】最长公共子序列

P1439 【模板】最长公共子序列

时间:2024-02-17 20:56:25浏览次数:19  
标签:最大 int mid len P1439 公共 序列 模板

首先找最大公共子序列,可以轻松想到 $O(n^2)$ 的 dp 转移式子,$f_{i,j}=max\begin{cases}f_{i-1,j}&i>0\
f_{i,j-1}&j>0\
f_{i-1,j-1}+1&i>0,j>0,A_i=A_j
\end{cases}$

但是我们发现最后 $n\le10^5$ 所以 $n^2$ 的复杂度不够优,这个时候再看题目,发现 A,B 都是 1~n 的排列,由此可知 A,B 中每个 1~n 之间的数都有且仅有一个,而最大公共子序列就是 A,B 中最大的相同的子序列,那么当我们把所有 $B_i$ 改为 $B_i$ 在 A 中的位置,那么要求的 A,B 最大公共子序列实际就是现在的 B 中的最大上升子序列。

求最大上升子序列,有一种 $O(n\log_2n)$ 的方法。

for (int i = 1;i <= n; ++ i)//n为a的长度
    f[i] = 2e9 + 7;     //f[i]是长度为i的上升子序列的最后一个值
f[1] = a[1];
int len = 1;
//初始化
for (int i = 1;i <= n; ++ i) {
    if (a[i] > f[len]) {
        f[++ len] = a[i];
        continue;
    }
    int l = 0, r = len, mid;
    while (l <= r) {
        mid = l + r >> 1;
        if (f[mid] >= a[i]) r = mid - 1;
        else l = mid + 1;
    }
    if (a[i] < f[l]) f[l] = a[i];
}

分析:当 $a_i$ 比 $f_i$ 的最大小的话,那么它替掉那个数不会影响后面的贡献。

所有本题就可以用 $O(nlog_2n)$ 的复杂度解决。

#include <cstdio>
using namespace std;
const int N = 1e5 + 5;
int a[N];
int mp[N];
int f[N], n, maxn[N];
int main() {
    scanf ("%d", &n);
    for (int i = 1;i <= n; ++ i) {
        int tmp;
        scanf ("%d", &tmp);
        mp[tmp] = i;
    }
    for (int i = 1;i <= n; ++ i) {
        int tmp;
        scanf ("%d", &tmp);
        a[i] = mp[tmp];
    }
    for (int i = 1;i <= n; ++ i)
        f[i] = 2e9 + 7;
    f[1] = a[1];
    int len = 1;
    for (int i = 1;i <= n; ++ i) {
        if (a[i] > f[len]) {
            f[++ len] = a[i];
            continue;
        }
        int l = 0, r = len, mid;
        while (l <= r) {
            mid = l + r >> 1;
            if (f[mid] >= a[i]) r = mid - 1;
            else l = mid + 1;
        }
        if (a[i] < f[l]) f[l] = a[i];
    }
    printf ("%d\n", len);
    return 0;
}

标签:最大,int,mid,len,P1439,公共,序列,模板
From: https://www.cnblogs.com/Assassins-Creed/p/18018377

相关文章

  • P3384 【模板】重链剖分/树链剖分 - SGT && 重链剖分
    本题是非常非常非常纯粹的树剖,利用了重链剖分后下标的性质不多说上代码就好了#include<cstdio>#include<vector>#definelllonglongusingnamespacestd;constintN=1e5+5;intn,m,r;llp,a[N],b[N];vector<int>V[N];intfa[N],dep[N],siz[N],hson[N]......
  • 快读快写模板
    快读函数点击查看代码intread(){intsign=1,re_in=0;charc=getchar();while(c<'0'||c>'9'){if(c=='-')sign=-1;c=getchar();}while(c>='0'&&c<='9'){......
  • Vue.js前端框架之vite+vue+naive前端项目模板
    1.搭建Vue示例项目npmcreatevue cdvue-demo:进入项目目录npminstall:安装所有依赖npmrundev:启动项目2.了解Vue开发和工作原理2.1package.json类似于Python项目中pyproject.toml,包含了项目名称、版本、命令、依赖、设定2.2index.html浏览器访问到的HTML文件 ......
  • 【常见问题】Java 8 date time type `java.time.LocalDateTime` not supported by def
    问题描述将一个包含LocalDateTime对象的集合进行序列化和反序列化时,可能会遇到以下异常:Causedby:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:Java8date/timetype`java.time.LocalDate`notsupportedbydefault:addModule"com.fasterxml.jack......
  • 【模板】多项式全家桶(多项式初等函数(部分))
    【模板】多项式初等函数同时作为https://github.com/caijianhong/template-poly的document。杂项数域为\(\mathbbF_{998244353}\),所以定义了mint为modint<998244353>。poly是多项式的类型,从std::vector<mint>继承而来。poly的构造函数如下:poly();explicitpoly(......
  • 【题解】P4722 【模板】最大流 加强版 / 预流推进
    更好阅读体验CHAPTER0废话1.常见的最大流算法可以大致分为两种:找增广路和预流推进2.从理论时间复杂度上界来看,找增广路算法的最坏时间复杂度为\(O(n^2m)\),而预流推进算法的最坏时间复杂度为\(O(n^2\sqrt{m})\),看起来预流推进要显然优于找增广路,但在实际应用(尤指OI)中,由于包......
  • jackson序列化问题
    在对对象进行jackson序列化的时候,有时候会出现序列化后的变量名称大小写错误的情况。测试的实体类TestEntity2如下:public class TestEntity2 {    private String aBcd;    private String qWER;    private String qWERty;    private String qWERty......
  • 归并排序模板
    #include<bits/stdc++.h>usingnamespacestd;constintN=1e5+10;intn,s[N],res[N];voidmerge_sort(ints[],intl,intr){intmid=(l+r)>>1;if(l>=r)return;merge_sort(s,l,mid);merge_sort(s,mid+1,r);inti=l,k=0,j......
  • 二叉树遍历问题模板
    在二叉树遍历问题中,有三种常见的遍历方式:前序遍历、中序遍历和后序遍历。以下是这三种遍历方式的递归模板:1.前序遍历(PreorderTraversal):defpreorderTraversal(root):ifnotroot:return[]result=[]result.append(root.val)#处理当前节点......
  • 回溯算法模板
    回溯算法的模板通常包含递归函数和回溯过程。以下是一个通用的回溯算法模板:defbacktrack(start,path,other_parameters):#满足结束条件时,将当前路径加入结果ifsatisfies_end_condition:result.append(path[:])return#从start开始遍历可......