最长公共子序列(动态规划+二分)
用f[n]存储最长公共子序列,用a[i]来存储数组, cnt代表最长公共序列的长度,
遍历时用a[i]遍历,每次遍历时用a[i]与f[cnt]比较大小,
如果a[i]>f[cnt-1],则f[cnt++]=a[i];
否则,用二分的方法将a[i]插入在f[n]这个数组中;
代码如下:
#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e7+10;
int n,cnt;
int a[N],dp[N];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}dp[cnt++]=a[1];
for(int i=1;i<=n;i++){
if(a[i]>dp[cnt-1]){
dp[cnt++]=a[i];
}else {
ll l=0,r=cnt-1;
while(l<r){
ll mid=(l+r)>>1;
if(a[i]<=dp[mid]){
r=mid;
}else{
l=mid+1;
}
}dp[r]=a[i];
}
}cout<<cnt;
// for(int i=0;i<cnt;i++){
// cout<<dp[i]<<" ";
//}
return 0;
}