难度:普及/提高-
题目类型:动规
提交次数:1
涉及知识:线性动规
题目描述
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设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 #include<iostream> 2 using namespace std; 3 int a[105]; 4 int d1[105]; 5 int d2[105]; 6 int n; 7 int main(){ 8 int i, j; 9 cin>>n; 10 for(i = 0; i < n; i++){ 11 cin>>a[i]; 12 d1[i] = 1; 13 d2[i] = 1; 14 } 15 for(i = 0; i < n; i++) 16 for(j = 0; j < i; j++) 17 if(a[j]<a[i]) 18 d1[i] = max(d1[i], d1[j]+1); 19 for(i = n; i >= 0; i--) 20 for(j = n; j > i; j--) 21 if(a[i]>a[j]) 22 d2[i] = max(d2[i], d2[j]+1); 23 int maxx = 0; 24 for(i = 0; i < n; i++) 25 maxx = max(d1[i]+d2[i], maxx); 26 cout<<n-maxx+1; 27 return 0; 28 }
备注:
十五分钟写完一道题∩_∩,对于这种线性动态规划已经轻车熟路啦。跟登山基本上一模一样,最长上升子序列,从前往后找一次再从后往前找一次,最后找一个最长的“合唱队形”。注意最后的答案是总人数减去这个队形人数,而因为队形人数最高的那人重复算了两次,所以要加一~