链接: 导弹拦截(洛谷)
你所需要的前置知识
1.LIS,LCS,LICS的掌握
2.二分或常用STL库中如upper_bound lower_bound
思路
观察数据量,必须使用nlogn才能满分 **
1.找到序列中最长不上升子序列**。
2.找到序列中最长上升子序列。(Dilworth定理)
代码
//使用nlongn方法找出双序列。
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 101000;
int a[N],b[N]; //a:最长不上升 b:最长不下降
int n,len[N],k,T; // len为原序列
bool cmp(int x,int y){
return x>y; //自定降序upper_bound逻辑
}
int main(){
while(cin>>len[n])n++;
a[k]=b[T]=len[0]; //初始化,载入双序列第一位
for(int i=1;i<n;i++){
if(len[i]<=a[k]){
a[++k]=len[i];
}
else if(len[i]>a[k]){
int pos=upper_bound(a,a+k,len[i],cmp)-a; // 竞赛中常用这种方式 用int表示坐标位置
a[pos]=len[i];
}
if(len[i]<=b[T]){
int pos=lower_bound(b,b+T,len[i])-b;
b[pos]=len[i];
}
else if(len[i]>b[T]){
b[++T]=len[i];
}
}
cout<<k+1<<endl;
cout<<T+1<<endl;
return 0;
}
版权声明:本文为qq_37411905原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。