洛谷P1439

这道题也给了我很多的思考,因为很久没有做过LIS和KLCS的题了

  • 为什么能采用二分
    因为f数组保存的是LCS长度为i时的最小末尾的值,可以证明f数组一定是单调的,并且是严格单调的
  • 为什么要保存末尾最小的值
    基于贪心的思想,显然相同长度的LCS末尾最小的有更大的机会递推到长度更长的LCS
#include<iostream>
#include<utility>
using namespace std;
typedef long long ll;
#define fi(i,a,b) for(int i = a; i <= b; ++i)
#define fr(i,a,b) for(int i = a; i >= b; --i)
#define x first
#define y second
#define sz(x) ((int)(x).size())
#define pb push_back
using pii = pair<int,int>;
//#define DEBUG
const int N = 1e5 + 5;
int mapp[N];
int s[N];
int f[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    fi(i,1,n) cin >> s[i];
    fi(i,1,n) {
        int x;
        cin >> x;
        mapp[x] = i;
    }
    f[1] = mapp[s[1]];
    int len = 1;
    fi(i,2,n){
        int l,r,mid;
        if(mapp[s[i]] > f[len]){
            f[++len] = mapp[s[i]];
        }
        else{
            l = 1,r = len;
            while(l < r){
                int mid = l + r >> 1;
                if(mapp[s[i]] < f[mid]) r = mid;
                else l = mid + 1;
            }
            f[l] = mapp[s[i]];
        }
    }
    cout << len << endl;
#ifdef DEBUG
    //freopen(D:\in.txt,r,stdin);
#endif
    return 0;
}
posted @ 2022-03-01 17:02  Sun-Wind  阅读(20)  评论(0编辑  收藏  举报