合唱队形(DP)

Posted darkfiremater

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合唱队形(DP)相关的知识,希望对你有一定的参考价值。

【题目】
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,
他们的身高分别为T1,T2,…,TK,则他们的身高满足  T1 < T2  ...<  Ti  >  Ti+1  >  …  >TK(1<=i<=K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
【输入格式】
第一行是一个整数N(2<=N<=100),表示同学的总数。
下来n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)。
【输出格式】
包括一行,这一行只包含一个整数,就是最少需要几位同学出列。
【样例输入】
8
186 186 150 200 160 130 197 220
【样例输出】
4

思路:

  正着求一遍最长上升子序列和反着求一遍最长上升子序列即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iomanip>
 5 #include<stdio.h>
 6 #include<math.h>
 7 #include<cstdlib>
 8 #include<set>
 9 #include<map>
10 #include<stack>
11 #include<queue>
12 #include<vector>
13 #include<set>
14 #define ll long long int
15 #define INF 0x7fffffff
16 #define mod 1000000007
17 #define me(a,b) memset(a,b,sizeof(a))
18 #define PI acos(-1.0)
19 #define mian main
20 //size_t npos=-1;
21 //ios::sync_with_stdio(0),cin.tie(0);
22 using namespace std;
23 const int N=1e5+5;
24  
25 int main()
26 {
27     int n,a[105],dp1[105],dp2[105];
28     cin>>n;
29     for(int i=0;i<n;i++)
30         cin>>a[i];
31     for(int i=0;i<n;i++){
32         dp1[i]=1;
33         for(int j=0;j<i;j++){
34             if(a[j]<a[i])
35                 dp1[i]=max(dp1[i],dp1[j]+1);
36         }
37     }
38     for(int i=n-1;i>=0;i--){
39         dp2[i]=1;
40         for(int j=n-1;j>i;j--){
41             if(a[j]<a[i])
42                 dp2[i]=max(dp2[i],dp2[j]+1);
43         }
44     }
45     int ans=0;
46     for(int i=0;i<n;i++){
47         ans=max(ans,dp1[i]+dp2[i]-1);
48     }
49     cout<<n-ans<<endl;
50 }

 

以上是关于合唱队形(DP)的主要内容,如果未能解决你的问题,请参考以下文章

合唱队形(DP)

合唱队形

动态规划合唱队形 luogu-

合唱队形

洛谷P1091合唱队形

Luogu P1091 合唱队形