題目描述:給定乙個整型陣列, 求這個陣列的最長嚴格遞增子串行的長度。 譬如序列1 2 2 4 3 的最長嚴格遞增子串行為1,2,4或1,2,3.他們的長度為3。
輸入:輸入可能包含多個測試案例。
對於每個測試案例,輸入的第一行為乙個整數n(1<=n<=100000):代表將要輸入的序列長度
輸入的第二行包括n個整數,代表這個陣列中的數字。整數均在int範圍內。
輸出:對於每個測試案例,輸出其最長嚴格遞增子串行長度。
樣例輸入:
44 2 1 3
51 1 1 1 1
樣例輸出:
21
參考《程式設計之美》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 我們可以得到一些...