第九章 動態規劃-1264:【例9.8】合唱隊形

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章