//11106287 c00h00g 1836 Accepted 432K 47MS G++ 1634B 2012-12-13 16:32:05
//一遍AC,哈哈
//题意,我们只需分三种情况讨论,第一种情况是从左到右求最长上升子序列
//第二种情况是从右向左求最长上升子序列 ,第三种情况是^形状的,从中间选一个点,分别求
//从最左边到该点最长上升子序列+从最右边到该点最长上升子序列 ,然后求三者的最大值就OK了
#include<stdio.h>
#include<stdlib.h>
double a[1005];
//left right用于求从左到右和从右到做的最长上升子序列
int left[1005];
int right[1005];
//maxL maxR表示从左边到该点和从右边到该点的最长上升子序列
int maxL[1005];
int maxR[1005];
int n;
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%lf",&a[i]);
left[i]=right[i]=1;
maxL[i]=maxR[i]=1;
}
//寻找最长递增子序列
//从左到右
int res=-1;
maxL[0]=1;
for(int i=1;i<n;i++){
int Max=-1;
for(int j=0;j<i;j++){
if(a[i]>a[j]&&left[j]>Max){
Max=left[j];
}
}
//找到的话更新dp[i]
if(Max!=-1){
left[i]=Max+1;
}
if(res<left[i])
res=left[i];
maxL[i]=res;
}
int res1=-1;
maxR[n-1]=1;
for(int i=n-2;i>=0;i--){
int Max=-1;
for(int j=n-1;j>i;j--){
if(a[i]>a[j]&&right[j]>Max){
Max=right[j];
}
}
if(Max!=-1){
right[i]=Max+1;
}
if(res1<right[i])
res1=right[i];
maxR[i]=res1;
}
//寻找两端的情况
int res2=-1;
for(int i=0;i<n-1;i++){
if(res2<maxL[i]+maxR[i+1])
res2=maxL[i]+maxR[i+1];
}
int ans=0;
if(res>res1)
ans=res;
else
ans=res1;
if(ans<res2)
ans=res2;
printf("%d\n",n-ans);
}
return 0;
}
POJ 1836
最新推荐文章于 2019-03-29 13:33:53 发布