求助! 50pts求调,过测试点1,3,4,5,6
查看原帖
求助! 50pts求调,过测试点1,3,4,5,6
705081
Memory_Lin楼主2022/11/7 20:24

时间复杂度是O(n^2 logn) 思路是枚举每个点i,然后分别算出以i为起始点的左右单调下降子序列(严格单调),然后minn=min{ n-len1-len2+1}

#include<bits/stdc++.h>
using namespace std;
const int N=100+10;
const int Inf=0x3f;
int n,a[N],len1=1,len2=1,minn=Inf;
int f1[N],f2[N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){//O(n^2*logn) 
		memset(f1,0x3f,sizeof(f1));len1=1;
		memset(f2,0x3f,sizeof(f2));len2=1;
		f1[1]=f2[1]=a[i];
		for(int j=i;j>=1;j--){
			int l=0,r=len1,mid;
			if(a[j]>=a[i]&&j!=i) continue; //确保以i点为首(下方同理)
			if(f1[len1]>a[j]){
				f1[++len1]=a[j];
			}else{
				while(l<r){
					mid=(l+r)/2;
					if(a[j]>=f1[mid]) r=mid;
					else l=mid+1;
				}
				f1[l]=max(f1[l],a[j]);
			} 
		}
		for(int j=i;j<=n;j++){
			int l=0,r=len2,mid;
			if(a[j]>=a[i]&&j!=i) continue;
			if(f2[len2]>a[j]){
				f2[++len2]=a[j];
			}else{
				while(l<r){
					mid=(l+r)/2;
					if(a[j]>=f2[mid]) r=mid;
					else l=mid+1;
				}
				f2[l]=max(f2[l],a[j]);
			}
		}
		minn=min(minn,n-(len1+len2-1));
	}
	printf("%d\n",minn);
    return 0;
}

2022/11/7 20:24
加载中...