zoukankan      html  css  js  c++  java
  • 【题解】P1439 【模板】最长公共子序列

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

    题解

    f[]维护当前最长的公共子序列,f[i]是这条子序列的第i个数在a中的位置。易知f[]是递增的。
    对于b的第i个数b[i],找到其在a中的位置mp[b[i]],如果mp[b[i]]大于f[len],说明b[i]这个数可以加到当前最长子序列后面。
    不然的话要想把b[i]这个数加到子序列里,我们可以根据f[]单调的性质二分在f[]中找到mp[b[i]]的位置f[l]。由于同样长的一条链的最后一个元素,他在a[]中出现的位置靠前一些,答案就越不会更差,所以如果f[l]要比mp[b[i]]大,就更新。

    代码

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    int n, a[100010], b[100010], mp[100010], f[100010]/*以b[i]为结尾的最长公共子序列在a中的位置*/, len;
    int main(){
    	scanf("%d",&n);
    	for(int i = 1; i <= n; ++i){
    		scanf("%d", &a[i]);
    		mp[a[i]] = i;
    	}	
    	for(int i = 1; i <= n; ++i)	scanf("%d", &b[i]);
    	for(int i = 1; i <= n; ++i){
    		int l = 0, r = len, mid;
    		if(mp[b[i]] > f[len])	f[++len] = mp[b[i]];
    		else{
    			while(l < r){
    				mid = l + r >> 1;
    				if(f[mid] > mp[b[i]])	r = mid;
    				else l = mid + 1;
    			}
    			f[l] = min(mp[b[i]], f[l]);
    		} 
    	}
    	printf("%d
    ", len);
    	return 0;
    }
    
  • 相关阅读:
    场景调研
    手机搜狗输入法体验
    1到一个整数之间1的个数
    寻找水王
    成套卖书最大优惠问题
    面向对象--多态
    抽象类和接口
    面向对象思想--继承
    面向对象思想--封装
    变量和参数传递
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/14493535.html
Copyright © 2011-2022 走看看