解題思路
實際上這是一道簡單動態規劃的題。但是一眼看上去不是很直觀。題目所謂的合唱隊形就是乙個最長上公升子串行的拼接。只要求出從佇列首到位置 i 的最長上公升子串行長度加上從隊尾開始到位置 i 的最長上公升子串行的長度就能求出合唱隊形的總長度。 我們還知道總的人數,減一下就能得出要出列的人數了。
求最長上公升子串行
現在有乙個序列,要求他的最長上公升子串行。直觀上並不是很好求得,反過來看的話就能比較好理解:
現在對於總序列裡的第i個元素來說,包含元素i的最長子序列是多少呢?如果i前面有能構成最長上公升序列的(設它為j),而且i數值比j大,那很顯然到第i個元素(包含元素i)的最長子序列是到第j個元素的最長子序列+1;否則到第i個元素(包含元素i)的最長子序列就是是1。因為前面沒有比他更小的了,只有自身構成乙個子串行。
參考**1
//
#include#include#includevoid getlisa(int *parr, int len, int* pres); //求最長上公升子串行
void getldsa(int *parr, int len, int* pres); //求最長下降子串行---或者說從後往前的上公升序列
void main()
printf("%d\n", len - lis[index] - lds[index]+1);
// system("pause");
}void getlisa(int *parr, int len,int *pres)
}void getldsa(int *parr, int len, int *pres)
}
參考**2
//
#include using namespace std;
const int maxn = 100 + 1;
int main()
for(int i=1; ia[j] && lis[i] < lis[j]+1)
lis[i] = lis[j] + 1;
for(int i=len-2; i>=0; --i)
for(int j=len-1; j>i; --j)
if(a[i] > a[j] && lds[i] < lds[j]+1)
lds[i] = lds[j] + 1;
int maxl = 0;
for(int i=0; i
華為OJ合唱隊
描述 計算最少出列多少位同學,使得剩下的同學排成合唱隊形 說明 n位同學站成一排,老師要請其中的 n k 位同學出列,使得剩下的k位同學排成合唱隊形。合唱隊形是指這樣的一種隊形 設k位同學從左到右依次編號為1,2 k,他們的身高分別為t1,t2,tk,則他們的身高滿足存在i 1 i k 使得titi...
華為oj 合唱隊
這個題目可以分解成正序和逆序的最大上公升子串行的問題來處理,對每個數字存放以當前數字為結尾時的最大上公升子串行數,只需要對前面的每個數進行比較,找到比當前數字小的數字,並且上公升子串行長度最大的作為當前的最大值,即for i 1 ia j dp j 1 dp i dp i dp j 1 最後對每個數...
華為OJ 初級 合唱隊
題目描述 計算最少出列多少位同學,使得剩下的同學排成合唱隊形 說明 n位同學站成一排,老師要請其中的 n k 位同學出列,使得剩下的k位同學排成合唱隊形。合唱隊形是指這樣的一種隊形 設k位同學從左到右依次編號為1,2 k,他們的身高分別為t1,t2,tk,則他們的身高滿足存在i 1 i k 使得ti...