1264:【例9.8】合唱隊形
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 6636 通過數: 3248
【題目描述】
N位同學站成一排,音樂老師要請其中的(N−K)位同學出列,使得剩下的K位同學排成合唱隊形。
合唱隊形是指這樣的一種隊形:設K位同學從左到右依次編號爲1,2,…,K,他們的身高分別爲T1,T2,…,TK,則他們的身高滿足T1<T2<…<Ti,Ti>Ti+1>…>TK(1≤i≤K)。
你的任務是,已知所有N位同學的身高,計算最少需要幾位同學出列,可以使得剩下的同學排成合唱隊形。
【輸入】
輸入的第一行是一個整數N(2≤N≤100),表示同學的總數。第二行有n個整數,用空格分隔,第i個整數Ti(130≤Ti≤230)是第i位同學的身高(釐米)。
【輸出】
輸出包括一行,這一行只包含一個整數,就是最少需要幾位同學出列。
【輸入樣例】
8
186 186 150 200 160 130 197 220
【輸出樣例】
4
【提示】
對於50%的數據,保證有n≤20;
對於全部的數據,保證有n≤100。
======================================
思路:求出隊不要的人數,首先,high[i] 身高的數組,f[i][0] 表示從左向右身高遞增的人數序列,其中f[i][0]爲同學1到i間 (包括同學i) 身高滿足遞增順序的最多人數。f[i][1]從右向左身高遞增的人數序列,max{f[i][0]+f[i][1]}-1;因爲第i個同學被計算兩次所以減一.(劃線標記說明了)
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int high[105],f[105][2];
int main(){
int n, ans = 0;
cin >> n;
memset(f,0,sizeof(f));
for(int i = 1; i <= n; i++)
{
cin >> high[i];
f[i][0] = f[i][1] = 1;//初始值爲1 邊界條件
}
for(int i = 1 ; i <= n; i++)//按照從左向右的順序計算
for(int j = i - 1 ; j > 0 ;j--)
if(high[i] > high[j])
f[i][0] = max(f[i][0],f[j][0] + 1);
for(int i = n; i > 0 ;i--)//按照從右向左的順序計算
for(int j = n; j > i ; j--)
if(high[i] > high[j])
f[i][1] = max(f[i][1],f[j][1] + 1);
for(int i = 1; i <= n; i++)
ans = max(ans, f[i][0] + f[i][1]);
cout << n - ans + 1 << endl; //計算合唱隊的人數max其中一個人被重複計算!出列人數(不要的人數)
return 0;
}