洛谷 P1091 合唱队形 题解

Posted

tags:

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

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:https://www.luogu.org/problem/show?pid=1091

题目描述

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:
8
186 186 150 200 160 130 197 220
输出样例#1:
4

说明

对于50%的数据,保证有n<=20;

对于全部的数据,保证有n<=100。

 

分析:

先求出上升序列,再求下降序列,最后枚举最优断点即可。

 

AC代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 
 7 int num[105],a[105];
 8 int up[105],down[105];
 9 
10 inline void read(int &x)
11 {
12     char ch = getchar(),c = ch;x = 0;
13     while(ch < 0 || ch > 9) c = ch,ch = getchar();
14     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
15     if(c == -)x = -x;
16     
17 }
18 
19 using namespace std;
20 
21 int main()
22 {
23     int n,ans = 0;
24     read(n);
25     for(int i = 1;i <= n;++ i)
26     {
27         read(num[i]),a[n-i+1] = num[i];
28         up[i] = 1,down[i] = 1;
29     }
30     for(int i = 2;i <= n;++ i)
31         for(int j = 1;j <= i;++ j)
32             if(num[j] < num[i])
33                 up[i] = max(up[j]+1,up[i]);
34     for(int i = 2;i <= n;++ i)
35         for(int j = 1;j <= i;++ j)
36             if(a[j] < a[i])
37                 down[i] = max(down[j]+1,down[i]);
38     for(int i = 1;i <= n;++ i)
39         ans = max(ans,up[i]+down[n-i+1]);        
40     printf("%d\n",n-ans+1);
41     return 0;
42 }

 

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

codevs1058 合唱队形==洛谷P1091 合唱队形

洛谷P1091合唱队形

[NOIP2004] 提高组 洛谷P1091 合唱队形

模板LIS模板 洛谷P1091 [NOIP2004提高组]合唱队形 [2017年4月计划 动态规划11]

[P1091]合唱队列 - 动态规划

Luogu P1091 合唱队形