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

题目描述

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

输入格式

第一行是一个数 n。

接下来两行,每行为 n 个数,为自然数 1,2,…,n 的一个排列。

输出格式

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

输入输出样例

输入 

5 
3 2 1 4 5
1 2 3 4 5

输出 

3

说明/提示

  • 对于 50% 的数据, n≤103;
  • 对于 100% 的数据, n≤105。

代码

无注释版

#include
#define int long long
using namespace std;
int a[100010],b[100010],s[100010];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin>>n;
	int x;
	for(int i=1;i<=n;i++){
		cin>>x;
		a[x]=i;
	}
	for(int i=1;i<=n;i++){
		cin>>x;
		b[i]=a[x];
	}  
	int cnt=0;
	s[0]=-2e9;
	for(int i=1;i<=n;i++){
		if(b[i]>s[cnt]) s[++cnt]=b[i];
		else{
			int l=1,r=cnt;
			while(l>1;
				if(s[mid]>=b[i]) r=mid;
				else l=mid+1;
			}
			s[l]=b[i]; 
		}
	} 
	cout<

有注释版 

#include  // 引入标准库,包含常用的C++库
#define int long long  // 定义long long为int类型,保证处理较大的数值时不会溢出
using namespace std;  // 使用标准命名空间

int a[100010], b[100010], s[100010];  // a数组记录排列P1中元素的位置,b数组记录转换后的P2序列,s数组用于动态规划的处理

signed main(){
    ios::sync_with_stdio(false);  // 禁用同步,提升输入输出速度
    cin.tie(0);  // 解绑cin和cout,提升效率
    cout.tie(0);  // 解绑cin和cout,提升效率

    int n;
    cin >> n;  // 输入排列的长度n
    int x;

    // 读取第一个排列P1,并记录每个元素的索引
    for (int i = 1; i <= n; i++) {
        cin >> x;  // 输入第i个元素
        a[x] = i;  // 将元素x在P1中的位置记录到a数组
    }

    // 读取第二个排列P2,并将P2的元素转化为P1中的位置索引
    for (int i = 1; i <= n; i++) {
        cin >> x;  // 输入P2中的元素
        b[i] = a[x];  // 将P2中的元素x映射为P1中的位置
    }

    int cnt = 0;  // 记录最长公共子序列的长度
    s[0] = -2e9;  // 初始化s数组的第0个元素为一个极小值

    // 计算最长上升子序列(LIS)的长度,这里用b数组(映射后的P2数组)来求解
    for (int i = 1; i <= n; i++) {
        if (b[i] > s[cnt])  // 如果当前元素大于s数组中的最大值,表示可以延长当前的LIS
            s[++cnt] = b[i];  // 增加LIS的长度
        else {
            int l = 1, r = cnt;
            while (l < r) {
                int mid = (l + r) >> 1;  // 计算中间位置,二分查找
                if (s[mid] >= b[i])  // 如果中间值大于等于当前值,缩小右边界
                    r = mid;
                else  // 否则,缩小左边界
                    l = mid + 1;
            }
            s[l] = b[i];  // 更新s数组,保证s数组是递增的
        }
    }

    cout << cnt << "\n";  // 输出最长公共子序列的长度
}

你可能感兴趣的:(洛谷,算法,数据结构,c++)