POJ DP题目,与NOI2004的排队很相似,但本题要更深入一点 即满足A1<A2<A3<...<Ai=>Ai+1>Ai+2>...>An ///使用最长递增(减)子序列,枚举中间人,但是需要注意中间人 ///有可能有两个人,譬如1 2 3 1 2 3 2 1;从枚举的地方向后查找最长递减序列中和中间人 ///比较,相等的情况下,再比较以查找到的元素为起点的最长递减序列的长度,以元素编号来区分 ///中间人是一个还是两个。 #include<stdio.h> int f_f[1005],f_b[1005]; double height[1005]; int n; int increase() { int i,j; f_f[0]=1; for(i=1;i<n;i++) { f_f[i]=1; for(j=0;j<i;j++) { if(height[i]>height[j]) f_f[i]=f_f[i]>f_f[j]+1?f_f[i]:f_f[j]+1; } } return 0; } int decrease() { int i,j; f_b[n-1]=1; for(i=n-2;i>=0;i--) { f_b[i]=1; for(j=n-1;j>i;j--) { if(height[i]>height[j]) f_b[i]=f_b[i]>f_b[j]+1?f_b[i]:f_b[j]+1; } } return 0; } int main() { while(scanf("%d",&n)==1) { int i,j,temp,t; for(i=0;i<n;i++) scanf("%lf",&height[i]); increase(); decrease(); /*for(i=0;i<n;i++) printf("%d ",f_f[i]); printf("/n"); for(i=0;i<n;i++) printf("%d ",f_b[i]); printf("/n");*/ int max=0; for(i=0;i<n;i++) { temp=f_b[i]; t=i; for(j=i+1;j<n;j++) if(height[i]==height[j]&&temp<=f_b[j]) { temp=f_b[j]; t=j; } //printf("temp:%d/n",temp); if(t==i) temp=f_f[i]+temp-1; else temp+=f_f[i]; max=max>temp?max:temp; //printf("#%d/n",max); } printf("%d/n",n-max); } return 0; }