合唱队形(LIS)

合唱队形    OpenJ_Bailian - 2711 

N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形。 
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, …, K,他们的身高分别为T1, T2, …, TK,则他们的身高满足T1 < T2 < … < Ti , Ti > Ti+1 > … > TK (1 <= i <= K)。 
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。 
Input

输入的第一行是一个整数N(2 <= N <= 100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130 <= Ti <= 230)是第i位同学的身高(厘米)。

Output

输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列。

Sample Input

8

186 186 150 200 160 130 197 220

Sample Output

4

简单的序列DP题,从左往右找出最长上升序列长度

再从右向左找出最长上升序列长度

再遍历一遍找到最大的和,就以这个作为中间的最高点

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <math.h>
 4 using namespace std;
 5 #define MAXN 105
 6 
 7 int n;
 8 int x[MAXN];
 9 int L[MAXN];
10 int R[MAXN];
11 
12 void Init()
13 {
14     for (int i=0;i<n;i++)
15     {
16         L[i]=1;
17         for (int j=i-1;j>=0;j--)
18         if (x[i]>x[j])
19             L[i] = max(L[i],L[j]+1);
20     }
21 
22     for (int i=n-1;i>=0;i--)
23     {
24         R[i]=1;
25         for (int j=i+1;j<n;j++)
26         if (x[i]>x[j])
27             R[i] = max(R[i],R[j]+1);
28     }
29 }
30 
31 int main()
32 {
33     while (scanf("%d",&n)!=EOF)
34     {
35         for (int i =0;i<n;i++)
36             scanf("%d",&x[i]);
37         Init();
38         int ans =0;
39         for (int i=0;i<n;i++)
40             if (L[i]+R[i]>ans)
41                 ans =L[i]+R[i];
42         printf("%d
",n-(ans-1));
43     }
44     return 0;
45 }
View Code
原文地址:https://www.cnblogs.com/haoabcd2010/p/6728811.html