You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

LIS+LCS专题

基础题

AcWing 895. 最长上升子序列

O(N^2)算法

状态表示 f[i]:以a[i]结尾的最长上升子序列长度

状态转移

    for (int i = 1; i <= n; i++) {
        f[i] = 1; //只有a[i]一个数
        for (int j = 1; j < i; j++)
            if (a[j] < a[i]) f[i] = max(f[i], f[j] + 1);
    }

答案

for (int i = 1; i <= n; i++) res = max(res, f[i]);

AcWing 896. 最长上升子序列 II

数据量增大:N<=100000 O(LogN*N)算法

 // 1、首个元素入栈
f[0] = a[0];

// 2、后续元素开始计算
for (int i = 1; i < n; i++) {
    if (a[i] > f[fl])
        f[++fl] = a[i];
    else
        //利用STL的二分在f中查找第一个大于等于a[i]的值,并完成替换
        *lower_bound(f, f + fl, a[i]) = a[i];
}    

也可以这样写

memset(f,-0x3f,sizeof f);
   
// 2、后续元素开始计算
for (int i = 1; i <= n; i++) {
    if (a[i] > f[fl])
        f[++fl] = a[i];
    else
        //利用STL的二分在f中查找第一个大于等于a[i]的值,并完成替换
        *lower_bound(f + 1, f + 1 + fl, a[i]) = a[i];
}

很明显,第一种写法性能更高,第二种写法有点暴力。

状态表示 f[i]表示长度为i的递增子序列中,末尾元素最小的是f[i]

答案 fl

状态转移f[]数组是一个单独上升的数组,这是可以二分的基础 ② 每个长度都争取替换掉前面记录数组中第一个大于等于自己的数字,以保证长度不变的情况下,数字最小,因为只有最小才能让后面的其它数字更容易接上去,机会才能更多。

AcWing 897. 最长公共子序列

状态表示 定义f[i][j]a[]i结尾,b[]j结尾的最长公共子序列长度

说明:没有说a[i]或者b[j]一定要出现在最长公共子序列当中!这个最长公共子序列,可能是a[]b[]的一些前序组成的,a[i],b[j]也可能没有对结果产生贡献。

  • a[i]==b[j]时,看一下两个字符串的前序,发现在少了a[i],b[j]后,转化为子问题f[i-1][j-1],问题转化为$f[i][j]=f[i-1][j-1]+1$

  • a[i] \neq b[j]时:

    • 如果a[i]不产生贡献,那么把它干掉f[i-1][j]
    • 如果b[j]不产生贡献,那么把它干掉f[i][j-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]);
        }

答案 f[n][m]

进阶题

AcWing 1017. 怪盗基德的滑翔翼 AcWing 1014. 登山 AcWing 482. 合唱队形 AcWing 1012. 友好城市 AcWing 1016. 最大上升子序列和 AcWing 1010. 拦截导弹 AcWing 187. 导弹防御系统 AcWing 272. 最长公共上升子序列

最长上升子序列 (LIS) 详解+例题模板 (全)