華爲OJ合唱隊

描述

計算最少出列多少位同學,使得剩下的同學排成合唱隊形

說明:

N位同學站成一排,音樂老師要請其中的(N-K)位同學出列,使得剩下的K位同學排成合唱隊形。 
合唱隊形是指這樣的一種隊形:設K位同學從左到右依次編號爲1,2…,K,他們的身高分別爲T1,T2,…,TK, 則他們的身高滿足存在i(1<=i<=K)使得

    Ti < T2 < ...< Ti-1 < Ti > Ti+1>...>TK

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

知識點 
循環 
運行時間限制 
0M 
內存限制 
0

輸入 
整數N 
一行整數,空格隔開,N位同學身高

輸出 
最少需要幾位同學出列 
樣例輸入 
8 186 186 150 200 160 130 197 200 
樣例輸出 
4

求最長上升子序列

現在有一個序列,要求他的最長上升子序列。直觀上並不是很好求得,反過來看的話就能比較好理解: 
現在對於總序列裏的第i個元素來說,包含元素i的最長子序列是多少呢?如果i前面有能構成最長上升序列的(設它爲j),而且i數值比j大,那很顯然到第i個元素(包含元素i)的最長子序列是到第j個元素的最長子序列+1;否則到第i個元素(包含元素i)的最長子序列就是是1。因爲前面沒有比他更小的了,只有自身構成一個子序列。

#include <iostream>
#include <vector>

using namespace std;

//最長升序
void GetUpSeries(vector<int> src, vector<int>& dst)
{
	int N = src.size();
	dst.resize(N);
	for (int i = 0; i < N; i++)
	{
		dst[i] = 1;
	}

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < i; j++)
		{
			if (src[j]<src[i] && dst[j] + 1>dst[i])
			{
				dst[i] = dst[j] + 1;
			}
		}
	}
}

//最長降序
void GetDownSeries(vector<int> src, vector<int>& dst)
{
	int N = src.size();
	dst.resize(N);
	for (int i = 0; i < N; i++)
	{
		dst[i] = 1;
	}

	for (int i = N-1; i >=0; i--)
	{
		for (int j = N-1; j > i; j--)
		{
			if (src[j]<src[i] && dst[j] + 1>dst[i])
			{
				dst[i] = dst[j] + 1;
			}
		}
	}
}

//動態規劃,dst記錄升序或降序元素個數,初始值爲1
int main(void)
{
	int N;
	cin >> N;

	vector<int> src;
	vector<int> dst1;
	vector<int> dst2;
	for (int i = 0; i < N; i++)
	{
		int tmp;
		cin >> tmp;
		src.push_back(tmp);
	}

	GetUpSeries(src, dst1);
	GetDownSeries(src, dst2);
	
	int max = 0;
	for (int i = 0; i < N;i++)
	{
		if (dst1[i] + dst2[i] > max)
		{
			max = dst1[i] + dst2[i];
		}
	}

	cout << N - max + 1;
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章