【洛谷】动态规划之最长公共子序列

 前言:

本系列目的是记录日常所刷的题,有的是自己想出来的题,有的是看了大佬题解后想明白的题

题目

P1439 【模板】最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

前提:

两个排列都是1到n的排列,说明元素都是相同的只是顺序不同,

思路:

把LCS转换成LIS 

原因:

通过离散化可以得到一个性质。

离散化步骤:

A:3 2 1 4 5
B:1 2 3 4 5
重新把A,B数组中的元素替换掉,使得A数组是其次递增的

标个号:把3标成a,把2标成b,把1标成c.…于是变成:
A: a b c d e

B: c b a d e
结论:最长公共子串的长度不会改变,又因为A数组是递增的,所以说在B数组中递增的子序列就是A的子序列

离散化代码:

for (int i = 1; i <= n; i++)
    {
        cin >> m;
        line[m] = i;
    }

整体代码

#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e5 + 10;
int n,m,total;
int ans[N],line[N];//line数组是第一个序列离散化后的数组,ans数组是第二个序列离散化后的数组
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> m;
        line[m] = i;
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> m;
        int search = line[m];
        if (search > ans[total])ans[++total] = search; else
        {  
            int l = 0, r = total;
            while (l <= r)
            {
                int mid = ans[(l + r)>> 2];
                if (search < mid)    
                    r = mid - 1;
                else
                    l = mid + 1;
            }
            ans[l] = search;
        }
    }
    cout << total;
}

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值