最长上升子序列
int t=0;
rep(i,1,n){
f[i]=1;
for(int j=1;j<i;j++)
if(c[i]>=c[j])
f[i]=max(f[i],f[j]+1);
t=max(t,f[i]);
}
由于DP版本复杂度为 O ( N 2 ) O(N^2) O(N2),不符合题目要求,所以使用二分
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define rep(i,x,y) for(int i = x; i <= y; i++)
#define per(i,x,y) for(int i = x; i >= y; i--)
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define endl '\n'
#define ms(x, n) memset(x,n,sizeof (x));
using ll = long long;
const int N = 1e6 + 10, mod = 998244353;
int T,n;
int a[N],b[N],c[N],f[N];
int main(){
cin>>T;
while(T--){
ms(f,0);
rep(i,1,n) a[i]=b[i]=c[i]=0;
cin>>n;
rep(i,1,n){
int x,y;
cin>>x>>y;
if(x==1 && y==0) a[i]=1;
else if(x==0 && y==1) a[i]=3;
else a[i]=2;
}
rep(i,1,n){
cin>>b[i];
c[i]=a[b[i]];
}
int t=0;
q[1]=-0x3f3f3f3f;
rep(i,1,n){
int l=0,r=t+1;
while(l+1<r){
int mid=l+r>>1;
if(q[mid]>c[i]) r=mid;
else l=mid;
}
t=max(t,r);
q[r]=c[i];
}
cout<<n-t<<endl;
}
return 0;
}