1. 程式人生 > >洛谷 P1091 合唱隊形 解題報告

洛谷 P1091 合唱隊形 解題報告

hit 區間 thml https 總數 -html 輸出格式 XSA href

題目描述

NN 位同學站成一排,音樂老師要請其中的( N-KN?K )位同學出列,使得剩下的 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

讀題可以發現,本題要求的是一個兩邊低中間高的序列,那麽為了保證出隊的人數盡量少,留下來的人數就要多,可以考慮把序列分成兩段,一段1---i,一段i+1---k,則題目轉化為在一段遞增(遞減)的區間中留下最多人;由此可以想到最長不下降子序列,由於有一邊是遞減的,所以從兩邊各跑一遍,然後跑一遍所有人,取max(f[左]+f[右]-1)即可(-1的原因是中間被多算了一次)

AC代碼:

#include<bits/stdc++.h>

using namespace std;

const int MAXN=105;

int f[2][MAXN],a[MAXN],n,maxx;

int main()

{

cin>>n;

for(int i=1;i<=n;i++)

cin>>a[i],f[0][i]=f[1][i]=1;


for(int i=1;i<=n;i++)

for(int j=1;j<i;j++)

if(a[i]>a[j])

f[0][i]=max(f[0][i],f[0][j]+1);

for(int i=n;i>=1;i--)

for(int j=n;j>i;j--)

if(a[i]>a[j])

f[1][i]=max(f[1][i],f[1][j]+1);

for(int i=1;i<=n;i++)

maxx=max(maxx,f[1][i]+f[0][i]-1);

cout<<n-maxx;

return 0;

}

參考大佬@XSamsara題解 


洛谷 P1091 合唱隊形 解題報告