array array array HDU - 6197 (LIS)

array array array

 题目链接:HDU - 6197 

题意:有n个数,要求去掉k个数后,剩下的数能构成非递减或者非递增序列,就输出 "A is a magic array.",反之输出"A is not a magic array.";

思路:去掉k个数之后能构成非递增序列则元数列中的LIS的长度不小于n-k,若能构成非递减序列,则原数列的最长递减子序列长度不小于n-k;其实就是求LIS,和最长递减子序列(我称之为ULIS);

用O(nlogn)的算法;

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn], b[maxn], c[maxn], n, k;
int find_first_bigger(int x, int l, int r){
	int ans=0;
	while(l<=r){
		int mid=(l+r)>>1;
		if(b[mid]<=x) l=mid+1;
		else r=mid-1;
	}
	return l;
}
int LIS(){
	int len=0, pos;
	for(int i=0; i<n; i++){
		if(len==0||a[i]>b[len]){
			b[++len]=a[i];
		}
		else{
			pos=find_first_bigger(a[i], 1, len);
			b[pos]=a[i];
		}
	}
	return len;
}
int find_first_less(int x, int l, int r){
	while(l<=r){
		int mid=(l+r)>>1;
		if(c[mid]>=x) l=mid+1;
		else r=mid-1;
	}
	return l;
}
int ULIS(){
	int len=0, pos;
	for(int i=0; i<n; i++){
		if(len==0||a[i]<c[len]){
			c[++len]=a[i];
		}
		else{
			pos=find_first_less(a[i], 1, len);
			c[pos]=a[i];
		}
	}
	return len;
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d%d", &n, &k);
		for(int i=0; i<n; i++)
			scanf("%d", &a[i]);
		int len1=LIS(), len2=ULIS();
		if(k>=n-len1||k>=n-len2) printf("A is a magic array.\n");
		else printf("A is not a magic array.\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Sirius_han/article/details/81407753