P1067 合唱队形
时间: 1000ms / 空间: 131072KiB / Java类名: Main
背景
NOIP2004 提高组 第三道
描述
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
输入格式
输入文件chorus.in的第一行是一个整数N(2<=N<=100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)。
输出格式
输出文件chorus.out包括一行,这一行只包含一个整数,就是最少需要几位同学出列。
测试样例1
输入
8
186 186 150 200 160 130 197 220
输出
4
备注
对于50%的数据,保证有n<=20;
对于全部的数据,保证有n<=100。
对于全部的数据,保证有n<=100。
题意:给你一个序列,为了使得序列满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。 需要删除一些数
问最少需要删除多少个数
题解:枚举中间点i 左边计算以i为结尾的最长上升子序列的长度l[i]
右边计算以i为起点的最长下降子序列的长度r[i] 取minx=min(minx,n-(l[i]+r[i]-1));
1 /****************************** 2 code by drizzle 3 blog: www.cnblogs.com/hsd-/ 4 ^ ^ ^ ^ 5 O O 6 ******************************/ 7 //#include<bits/stdc++.h> 8 #include<iostream> 9 #include<cstring> 10 #include<cstdio> 11 #include<map> 12 #include<algorithm> 13 #include<queue> 14 #include<cmath> 15 #define ll __int64 16 #define PI acos(-1.0) 17 #define mod 1000000007 18 using namespace std; 19 int n; 20 int a[105]; 21 int l[105],r[105]; 22 int main() 23 { 24 scanf("%d",&n); 25 for(int i=1;i<=n;i++) 26 scanf("%d",&a[i]); 27 int ans[105]; 28 int exm=0; 29 ans[0]=0; 30 for(int i=1;i<=n;i++) 31 { 32 if(a[i]>ans[exm]) 33 { 34 exm++; 35 ans[exm]=a[i]; 36 l[i]=exm; 37 } 38 else 39 { 40 int pos=lower_bound(ans+1,ans+exm,a[i])-ans; 41 ans[pos]=a[i]; 42 l[i]=pos; 43 } 44 } 45 exm=0; 46 ans[0]=0; 47 for(int i=n;i>=1;i--) 48 { 49 if(a[i]>ans[exm]) 50 { 51 exm++; 52 ans[exm]=a[i]; 53 r[i]=exm; 54 } 55 else 56 { 57 int pos=lower_bound(ans+1,ans+exm,a[i])-ans; 58 ans[pos]=a[i]; 59 r[i]=pos; 60 } 61 } 62 int minx=200; 63 for(int i=1;i<=n;i++) 64 minx=min(minx,n-(l[i]+r[i]-1)); 65 printf("%d ",minx); 66 return 0; 67 }