例如3,18,7,14,10,12,23,41,16,24。
若存在i1<i2<i3< … < ie 且有a(i1)<a(i2)< … <a(ie)則稱為長度為e的不下降序列。如上例中3,18,23,24就是一個長度為4的不下降序列,同時也有3,7,10,12,16,24長度為6的不下降序列。
下面是求一個最長不下降序列的pascal代碼
program max_rise(input,output);
const maxn=100;fname="q21.txt";
type Tlist=array[1..maxn,1..3] of integer;
var d:tlist;n:byte;
procedure init;
var
i:integer;
f:text;
begin
assign(f,fname);
reset(f);
readln(f,n);
for i:=1 to n do
begin
read(f,d[i,1]);
d[i,2]:=1;
d[i,3]:=0
end;
close(f);
end;
procedure make;
var
i,j,p:byte;
l:integer;
begin
for i:=n-1 downto 1 do
begin
l:=0;p:=0;
for j:=i+1 to n do
if (d[i,1]<d[j,1]) and (d[j,2]>l) then
begin
l:=d[j,2];
p:=j;
end;
if l>0 then
begin
d[i,2]:=l+1;
d[i,3]:=p;
end;
end;
end;
procedure output;
var
i,l,DMAX:byte;
begin
write('source:');
for i:=1 to n do write(d[i,1]:5);
writeln;
dmax:=d[1,2];
l:=1;
for i:=2 to n-1 do
if d[i,2]>dmax then
begin
dmax:=d[i,2];
l:=i;
end;
write('result is: ');
while l<>0 do
begin
write(d[l,1]:5);
l:=d[l,3];
end;
writeln;
writeln('max length=",dmax);
end;
begin
init;
make;
output;
end.
input:
10
3 18 7 14 10 12 23 41 16 24
output:
source: 3 18 7 14 10 12 23 41 16 24
result is: 3 7 10 12 23 41
max length = 6
最長不下降序列nlogn算法:
算法分析:
設 A[t]表示序列中的第t個數,F[t]表示從1到t這一段中以t結尾的最長上升子序列的長度,初始時設F [t] = 0(t = 1, 2, ..., len(A))。則有動態規劃方程:F[t] = max{1, F[j] + 1} (j = 1, 2, ..., t - 1, 且A[j] < A[t])。
現在,我們仔細考慮計算F[t]時的情況。假設有兩個元素A[x]和A[y],滿足
(1)x < y < t
(2)A[x] < A[y] < A[t]
(3)F[x] = F[y]
此時,選擇F[x]和選擇F[y]都可以得到同樣的F[t]值,那么,在最長上升子序列的這個位置中,應該選擇A[x]還是應該選擇A[y]呢?
很明顯,選擇A[x]比選擇A[y]要好。因為由於條件(2),在A[x+1] ... A[t-1]這一段中,如果存在A[z],A[x] < A[z] < a[y],則與選擇A[y]相比,將會得到更長的上升子序列。
再根據條件(3),我們會得到一個啟示:根據F[]的值進行分類。對於F[]的每一個取值k,我們只需要保留滿足F[t] = k的所有A[t]中的最小值。設D[k]記錄這個值,即D[k] = min{A[t]} (F[t] = k)。
注意到D[]的兩個特點:
(1) D[k]的值是在整個計算過程中是單調不上升的。
(2) D[]的值是有序的,即D[1] < D[2] < D[3] < ... < D[n]。
利 用D[],我們可以得到另外一種計算最長上升子序列長度的方法。設當前已經求出的最長上升子序列長度為len。先判斷A[t]與D[len]。若A [t] > D[len],則將A[t]接在D[len]後將得到一個更長的上升子序列,len = len + 1, D[len] = A [t];否則,在D[1]..D[len]中,找到最大的j,滿足D[j] < A[t]。令k = j + 1,則有A [t] <= D[k],將A[t]接在D[j]後將得到一個更長的上升子序列,更新D[k] = A[t]。最後,len即為所要求的最長上 升子序列的長度。
在 上述算法中,若使用樸素的順序查找在D[1]..D[len]查找,由於共有O(n)個元素需要計算,每次計算時的複雜度是O(n),則整個算法的 時間複雜度為O(n^2),與原來的算法相比沒有任何進步。但是由於D[]的特點(2),我們在D[]中查找時,可以使用二分查找高效地完成,則整個算法 的時間複雜度下降為O(nlogn),有了非常顯著的提高。需要注意的是,D[]在算法結束後記錄的並不是一個符合題意的最長上升子序列!
pascal代碼:
program nlogn;
var
d,a:array[0..100000] of longint;
len,i,k,n:longint;
Function min(t:longint):longint;
var s,w,mid:longint;
begin
s:=0;w:=len;
while s<w do begin
mid:=(s+w)div 2;
if d[mid]<t then s:=mid+1 else w:=mid;
end;
min:=s;
end;
begin
readln(n);
for i:=1 to n do read(a[i]);
readln;
len:=0;
d[0]:=-maxlongint;
for i:=1 to n do begin
if a[i]>d[len] then begin
inc(len);
d[len]:=a[i];
end else begin
k:=min(a[i]);
if d[k]>a[i] then d[k]:=a[i];
end;
end;
writeln(len);
end.
相關詞條
-
鬼吹燈
詳情請參見《鬼吹燈》條目 鬼吹燈 本書目錄: 引子 第一章 白紙人 第二章 鼠友 第三章 荒墳凶屍 第四章 大山裡的古墓 第五章...
-
國民黨五大主力
主力中建軍最早、歷史最長,在軍閥混戰、國共內戰中屢立戰功,為蔣介石與陳誠所...
第十八軍 第七十四軍 新六軍 新一軍 第五軍 -
國軍五大主力
是五大主力中建軍最早、歷史最長,在軍閥混戰、國共內戰中屢立戰功,為蔣介石...
第十八軍 整編第七十四師 新六軍 新一軍 第五軍 -
《上帝擲骰子嗎》
《上帝擲骰子嗎》 摘要 愛因斯坦:「一個人的價值,應該看他貢獻了什麼,而不是他取得了什麼。」 愛因斯坦說:「我不相信上帝是靠擲骰...
《上帝擲骰子嗎》 序 第一章 黃金時代 第二章 烏雲 第三章 火流星 -
空降兵特種大隊
,投入最長的運輸機。1989年9月報導南飛已生產727架Y-5,另一生產此機的石飛生產了不下250架,1996年仍在量產。Y-5最新型Y-5C自...,加速空降兵發展。一批新機、新傘、新炮等加入序列使空降兵能執行較大規模空降...
-
第十五空降軍
的輕雙翼螺旋槳運輸機,是中國批量最大,投入最長的運輸機。1989年9月報導南飛已生產727架Y-5,另一生產此機的石飛生產了不下250架...列為應急機動部隊,加速空降兵發展。一批新機、新傘、新炮等加入序列使空降兵...
概述 意義 來歷 編制 -
江西龍虎山
,是我國一姓嗣教時間最長的道派。百神受職之所的“大上清宮”,始建於東漢,為祖...
歷史淵源 基本簡介 名稱由來 景點介紹 景點文化 -
中國人民解放軍空降15軍
工業生產批量最大,投入時間最長的運輸機。據1989年9月的人民日報報導,南飛...了不下250架,直到1996年仍在量產中。Y-5的最新改型為Y-5C,自...機種從缺,而空軍運載能力又呈待提升的情形下,中國空軍的序列中將會出現...
-
中國軍史 中國“千歲軍”第15空降軍
式運輸機,也是中國航空工業生產批量最大,投入時間最長的運輸機。據...型飛機的石家莊飛機廠也生產了不下250架,直到1996年仍在量產中。Y-5...能力又呈待提升的情形下,中國空軍的序列中將會出現越來越多的IL-76運輸機...