1. 程式人生 > >P1091 合唱隊形

P1091 合唱隊形

ase set 輸入輸出 sca nbsp esp put 所有 老師

題目描述

NN位同學站成一排,音樂老師要請其中的(N-KNK)位同學出列,使得剩下的KK位同學排成合唱隊形。

合唱隊形是指這樣的一種隊形:設K位同學從左到右依次編號為1,2,…,K1,2,,K,他們的身高分別為T_1,T_2,…,T_KT1?,T2?,,TK?, 則他們的身高滿足T_1<...<T_i>T_{i+1}>…>T_K(1 \le i \le K)T1?<...<Ti?>Ti+1?>>TK?(1iK)。

你的任務是,已知所有N位同學的身高,計算最少需要幾位同學出列,可以使得剩下的同學排成合唱隊形。

輸入輸出格式

輸入格式:

共二行。

第一行是一個整數N(2 \le N \le 100)N(2N100),表示同學的總數。

第二行有nn個整數,用空格分隔,第ii個整數T_i(130 \le T_i \le 230)Ti?(130Ti?230)是第ii位同學的身高(厘米)。

輸出格式:

一個整數,最少需要幾位同學出列。

輸入輸出樣例

輸入樣例#1: 復制
8
186 186 150 200 160 130 197 220
輸出樣例#1: 復制
4


每次都是看到題解恍然大悟 真是弱雞

要求最少出隊 那麽就是求最長的合唱隊形
只要從左邊和右邊各遍歷一遍 求出dp 最長上升序列和下降序列 再枚舉中間點即可

#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,x,y) for(int i=(x);i<=(y);++i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define
RS(s) scanf("%s",s) #define LL long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define N 100005 #define inf -0x3f3f3f3f int dp[N]; int dp2[N]; int a[N]; int main() { int n; RI(n); rep(i,1,n) RI(a[i]); rep(i,1,n) { dp[i]=1; for(int j=1;j<i;j++) if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1); } for(int i=n;i>=1;i--) { dp2[i]=1; for(int j=n;j>i;j--) if(a[j]<a[i])dp2[i]=max(dp2[i],dp2[j]+1); } int maxx=0; rep(i,1,n) maxx=max(maxx,dp[i]+dp2[i]-1 ); cout<<n-maxx<<endl; return 0; }












P1091 合唱隊形