動態規劃之合唱隊形問題(最長遞增子串行變形)

2021-07-13 12:26:26 字數 1533 閱讀 2927

題目描述

n位同學站成一排,**老師要請其中的(n-k)位同學出列,使得剩下的k位同學不交換位置就能排成合唱隊形。

合唱隊形定義:設k位同學從左到右依次編號為1, 2, …, k,他們的身高分別為t1, t2, …, tk,

則他們的身高滿足t1 < t2 < … < ti, ti > ti+1 > … > tk (1 <= i <= k)。 

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

輸入輸入的第一行是乙個整數n,表示同學的總數。 

第一行有n個整數,用空格分隔,第i個整數ti是第i位同學的身高(厘公尺)。

輸出輸出包括一行,這一行只包含乙個整數,就是最少需要幾位同學出列。

解題思路

定義n位同學的身高陣列為a[n](注意這裡陣列長度不允許為變數,這裡只是為了理解將n寫如到中)。

【總體思路】:假設第i(0<= i <= n - 1)個同學為最高點,分別求出此時i左邊的最長遞增子串行長度inc1[i],i右邊的最長遞減子串行長度inc2[i],由於最高點i同時包括在了inc1[i]和inc2[i]之中,因此實際的合唱隊形的長度為inc1[i] + inc2[i] - 1。而我們求得的最後結果就是i從1到n - 1中,使得inc1[i] + inc2[i] - 1最大的情況。

【具體實現】:現在設i為下標,迴圈i從0到n-1,求得各種i值對應的inc1[i];迴圈i從0到n-1,求得各種i值對應的inc2[i]。最後迴圈i從0到n-1,求得各種i值對應的inc[i] + inc2[i] - 1最大的情況ans,然後n - ans即為出列同學的人數。

當i = 0的時候,最高點0左邊只有它自己,因此inc1[0] = 1;當i = n - 1的時候,最高點n - 1右邊只有它自己,因此inc2[n - 1] = 1;當i處於0到n - 1之間時的求法也很好理解,在求inc1[i]時,j = (0 ~ i - 1)的inc[j]已經得出來了,所以我們只需要比較在前面的這些序列中加上a[i]時的最長遞增序列,即在a[i]大於前面這些序列值的情況下inc[j] + 1最大的情況即為inc[i]。

源**如下:

#include #include using namespace std;

int inc1[200],inc2[200],a[200];

//inc1-->longest increase array from head to tail

//inc2-->longest increase array from tail to head

int main()

//inc2[i]是儲存以i為最高點時左邊的遞減子串行長度

inc2[n - 1] = 1;

for(i = n - 2; i >= 0; i--)

for(i = 0; i<=n; i++)

if(inc1[i] + inc2[i]-1 > ans)

ans = inc1[i] + inc2[i] - 1;

printf("%d\n",n-ans);

}return 0;

}

合唱隊形 動態規劃 最長遞增子串行

n位同學站成一排,老師要請其中的 n k 位同學出列,使得剩下的k位同學不交換位置就能排成合唱隊形。合唱隊形是指這樣的一種隊形 設k位同學從左到右依次編號為1,2,k,他們的身高分別為t1,t2,tk,則他們的身高滿足t1 t2 ti ti ti 1 tk 1 i k 你的任務是,已知所有n位同學的...

codevs合唱隊形 動態規劃求最長遞增子串行

題目描述 description n位同學站成一排,老師要請其中的 n k 位同學出列,使得剩下的k位同學排成合唱隊形。合唱隊形是指這樣的一種隊形 設k位同學從左到右依次編號為1,2 k,他們的身高分別為t1,t2,tk,則他們的身高滿足t1 ti 1 tk 1 i k 你的任務是,已知所有n位同學...

動態規劃 合唱隊形

一行數字要求從兩邊到中間依次增大,問給出的一行數字要去掉多少才能形成這種數列。可以任選乙個做中間數k,從1到n。然後求第乙個數到k的最長上公升子串行的長度la,再求最後乙個數到k的最長上公升子串行的長度lb。最後n la la 1 就是去掉的數字個數,減一是因為多算了乙個k。有些題需要幾個簡單的演算...