洛谷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;
}