P1020 [NOIP1999 普及组] 导弹拦截——快速掌握_CPP

P1020 [NOIP1999 普及组] 导弹拦截——快速掌握_CPP


链接: 导弹拦截(洛谷)

你所需要的前置知识

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版权协议,转载请附上原文出处链接和本声明。