1. 程式人生 > >jzxx1500題麻煩的聚餐

jzxx1500題麻煩的聚餐

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<iostream>
#include<set>
#include<map>
#include<vector>
#include<cstdlib>
using namespace std;
const int maxn = 30005;
const int inf = 200000010;
int n,a[maxn],cnt1,cnt2;
int g1[maxn],g2[maxn];
void initial()
{	for(int i=1; i<=n; i++)
	{
		g1[i]=inf;
		g2[i]=-inf;
	}
}
int find(int x)
{
	int A=1,B=cnt2,ans=0;
	while(A<=B)
	{
		int mid=A+B>>1;
		if(g2[mid]>=x)A=mid+1,ans=mid;
		else B=mid-1;
	}
	return ans;
}
int main()
{	//freopen("dinner.in","r",stdin);
	//freopen("dinner.out","w",stdout);
	scanf("%d",&n);
	for(int i=1; i<=n; i++)
		scanf("%d",&a[i]);
	initial();
	cnt1=1;
	g1[1]=a[1];
	for(int i=2; i<=n; i++)	{
		int t=upper_bound(g1+1,g1+cnt1+1,a[i])-g1;
		if(t>cnt1 || a[i]<g1[t])		{
			g1[t]=a[i];
		}
		cnt1=max(cnt1,t);
	}
	for(int i=1; i<=n; i++)
	{
		int t=find(a[i]);
		if(t+1>cnt2 || a[i]>g2[t+1])
		{
			g2[t+1]=a[i];
		}
		cnt2=max(cnt2,t+1);
	}
	int ans;
	ans=min(n-cnt1,n-cnt2);
	printf("%d",ans);
	return 0;
}