洛谷1091合唱队形

题目描述

N位同学站成一排,音乐老师要请其中的(NK)位同学出列,使得剩下的K位同学排成合唱队形。

合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,,K,他们的身高分别为T1,T2,,TK, 则他们的身高满足T1<...TTi+1​ >TK(1iK)。

你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入输出格式

输入格式:

 

共二行。

第一行是一个整数N(2N100),表示同学的总数。

第二行有n个整数,用空格分隔,第i个整数(130Ti230)是第ii位同学的身高(厘米)。

 

输出格式:

 

一个整数,最少需要几位同学出列。

 

输入输出样例

输入样例#1: 复制
8
186 186 150 200 160 130 197 220
输出样例#1: 复制
4

说明

对于50%的数据,保证有n20;

对于全部的数据,保证有n100。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 int i,j,n,a[105],f[2][105],ans;
 7 int main()
 8 {
 9     scanf("%d",&n);
10     for(i = 1;i <= n;i++)
11     {
12         scanf("%d",&a[i]);
13     }
14     a[0] = 0;
15     for(i = 1;i <= n;i++)//从1到n求最长列 
16     {
17         for(j = 0;j <= i;j++)
18         {
19             if(a[i] > a[j])
20             f[0][i] = max(f[0][i],f[0][j] + 1);
21         }
22     }
23     a[n + 1] = 0;
24     for(i = n;i >= 1;i--)//从n到1求最长列 
25     {
26         for(j = n + 1;j > i;j--)
27         {
28             if(a[i] > a[j])
29             f[1][i] = max(f[1][i],f[1][j] + 1);
30         }
31     }
32     for(i = 1;i <= n;i++)
33     {
34         ans = max(f[0][i] + f[1][i] - 1,ans);//枚举Ti,从1到Ti的最长列+从TK到Ti的最长列- 1(Ti被加了两次)
35     }
36     printf("%d",n - ans);
37     return 0;
38  } 

*****显然这个是一个区间DP呦,从前往后求最长上升序列,然后求从后往前求最长上升序列,最后枚举中间人的位置求出答案,吼吼吼

原文地址:https://www.cnblogs.com/rax-/p/9885642.html