luogu1091合唱队形
N位同学站成一排,音乐老师要请其中的(N−K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,…,K,他们的身高分别为T1,T2,…,TK 则他们的身高满足T1<...<Ti>Ti+1>…>TK(1≤i≤K)
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
输入输出格式
输入格式:
共二行。
第一行是一个整数N(2≤N≤100),表示同学的总数。
第二行有n个整数,用空格分隔,第i个整数Ti(130≤Ti≤230)是第i位同学的身高(厘米)。
输出格式:
一个整数,最少需要几位同学出列
有两种思路,一是枚举波峰,向两边扩展,二是正着做个lis,反着再做个lis,求和的最大值
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+5; 4 const int INF=1e9+7; 5 int n,ans; 6 int l[200],r[200],f[200],g[200]; 7 template <class t>void red(t &x) 8 { 9 x=0; 10 int w=1; 11 char ch=getchar(); 12 while(ch<'0'||ch>'9') 13 { 14 if(ch=='-') 15 w=-1; 16 ch=getchar(); 17 } 18 while(ch>='0'&&ch<='9') 19 { 20 x=(x<<3)+(x<<1)+ch-'0'; 21 ch=getchar(); 22 } 23 x*=w; 24 } 25 void input() 26 { 27 freopen("input.txt","r",stdin); 28 } 29 void read() 30 { 31 red(n); 32 for(int i=1;i<=n;++i) 33 { 34 red(l[i]); 35 r[i]=l[i]; 36 } 37 } 38 void work() 39 { 40 for(int i=1;i<=n;++i) 41 for(int j=0;j<i;++j) 42 if(l[i]>l[j]) 43 f[i]=max(f[i],f[j]+1); 44 for(int i=n;i>=1;--i) 45 for(int j=n;j>i;--j) 46 if(r[i]>r[j]) 47 g[i]=max(g[i],g[j]+1); 48 for(int i=1;i<=n;++i) 49 ans=max(ans,f[i]+g[i]); 50 printf("%d",n-ans); 51 } 52 int main() 53 { 54 input(); 55 read(); 56 work(); 57 return 0; 58 }