描述
計算最少出列多少位同學,使得剩下的同學排成合唱隊形
說明:
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;
}