九度OJ 1533 最長上公升子串行 動態規劃

2021-06-20 13:23:29 字數 1751 閱讀 2634

題目描述:給定乙個整型陣列, 求這個陣列的最長嚴格遞增子串行的長度。 譬如序列1 2 2 4 3 的最長嚴格遞增子串行為1,2,4或1,2,3.他們的長度為3。

輸入:輸入可能包含多個測試案例。

對於每個測試案例,輸入的第一行為乙個整數n(1<=n<=100000):代表將要輸入的序列長度

輸入的第二行包括n個整數,代表這個陣列中的數字。整數均在int範圍內。

輸出:對於每個測試案例,輸出其最長嚴格遞增子串行長度。

樣例輸入:

4

4 2 1 3

51 1 1 1 1

樣例輸出:

2

1

參考《程式設計之美》2.16

對於前面i個元素的任何乙個遞增子串行,如果這個子串行的最大的元素比array[i+1]小,那麼就可以將array[i+1]加在這個子串行後面,構成乙個新的子串行。

比如當i=4的時候,目標序列為:1,-1,2,-3,4,-5,6,-7最長遞增序列為:(1, 2),(-1, 2)。那麼,只要4>2,就可以把4直接增加到前面的子串行中形成乙個新的遞增子串行。

因此,我們希望找到前i個元素的乙個遞增子串行,使得這個遞增子串行的最大元素比array[i+1]小,且長度盡量地大。這樣將array[i+1]加在該遞增子串行後,便可找到以array[i+1]為最大元素的最長遞增子串行。

仍然假設在陣列的前i個元素中,以array[i]為最大元素的最長遞增子串行的長度為lis[i]。

同時,假設:

長度為1的遞增子串行最大元素的最小值為maxv[1];

長度為2的遞增子串行最大元素的最小值為maxv[2];

長度為lis[i]的遞增子串行最大元素的最小值為maxv[lis[i]]。

具體演算法實現如下:

#include #define max 100000

#define vmax 100001

#define min (-2147483647 - 1)

int bsearch (int maxv, int start, int end, int key)

else if (maxv[mid] > key)

else

return mid;

}return start;}

int lis (int data, int n)

else if (maxv[j] < data[i] && data[i] < maxv[j + 1])

}return nmaxlis;}

int main(void)

else if (maxv[mid] > key)

else

return mid;

}return start;}

int lis (int data, int n)

else if (maxv[j-1] < data[i] && data[i] < maxv[j])

}return nmaxlis;}

int main(void){

int data[max];

int n;

int i;

while (scanf ("%d", &n) != eof){

for (i=0; ihdoj上相似的題目:1025 -- constructing roads in jgshining's kingdom

參考資料:

九度 1533 最長上公升子串行

題目描述 給定乙個整型陣列,求這個陣列的最長嚴格遞增子串行的長度。譬如序列1 2 2 4 3 的最長嚴格遞增子串行為1,2,4或1,2,3.他們的長度為3。思路 1.樸素求解 lis,沒什麼可說的 2.又涉及到二分查詢,這次找的是大於等於 target 的最小值.時直接返回,這就簡單了.low hi...

最長上公升子串行 oj

time limit 3000 ms memory limit 65536 kib submit statistic problem description 乙個數的序列bi,當b 1 b 2 b s的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a 1,a 2,a n 我們可以得到一些上公升...

最長上公升子串行 OJ

最長上公升子串行 time limit 3000 ms memory limit 65536 kib submit statistic problem description 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些...