題目的意思是,兩行城市,從左到右為1,2,3……n個城市。上面的下面的城市要與上面某個的城市相連,在不出現相交的情況下,最多可以連多少條
最長上公升子串行的o(n*logn)演算法分析如下:
先回顧經典的o(n^2)的動態規劃演算法,設a[t]表示序列中的第t個數,dp[t]表示從1到t這一段中以t結尾的最長上公升子串行的長度,初始時設dp [t] = 0(t = 1, 2, ..., len(a))。則有動態規劃方程:dp[t] = max (j= 1, 2, ..., t - 1, 且a[j]
現在,我們仔細考慮計算dp[t]時的情況。假設有兩個元素a[x]和a[y],滿足
(1)x
(2)a[x]
(3)dp[x] = dp[y]
此時,選擇dp[x]和選擇dp[y]都可以得到同樣的dp[t]值,那麼,在最長上公升子串行的這個位置中,應該選擇a[x]還是應該選擇a[y]呢?
很明顯,選擇a[x]比選擇a[y]要好。因為由於條件(2),在a[x+1] ... a[t-1]這一段中,如果存在a[z],a[x]
再根據條件(3),我們會得到乙個啟示:根據dp的值進行分類。對於dp的每乙個取值k,我們只需要保留滿足dp[t] = k的所有a[t]中的最小值。設d[k]記錄這個值,即d[k] = min (dp[t] = k)。
注意到d的兩個特點:
(1) d[k]的值是在整個計算過程中是單調不上公升的。
(2) d的值是有序的,即d[1]
利用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]
在上述演算法中,若使用樸素的順序查詢在d[1]..d[len]查詢,由於共有o(n)個元素需要計算,每次計算時的複雜度是o(n),則整個演算法的時間複雜度為o(n^2),與原來的演算法相比沒有任何進步。但是由於d的特點(2),我們在d中查詢時,可以使用二分查詢高效地完成,則整個演算法的時間複雜度下降為o(nlogn),有了非常顯著的提高。需要注意的是,d在演算法結束後記錄的並不是乙個符合題意的最長上公升子串行!
例如2 5 4 6 3 8 7
2 3 6 7
nlogn的dp的思路大概就是給你乙個數,插到乙個陣列中,該位置已存在,就覆蓋它。也就是可以用二分查詢提高效率。
另為一種o(nlogn)演算法,這種演算法的操作如下:
開乙個棧,每次取棧頂元素top和讀到的元素temp做比較,如果temp > top 則將temp入棧;如果temp < top則二分查詢棧中的比temp大的第1個數,並用temp替換它。最長序列長度即為棧的大小top。
這也是很好理解的,對於x和y,如果x < y且stack[y] < stack[x],用stack[x]替換stack[y],此時的最長序列長度沒有改變但序列q的''潛力''增大了。
舉例:原序列為1,5,8,3,6,7
棧為1,5,8,此時讀到3,用3替換5,得到1,3,8;再讀6,用6替換8,得到1,3,6;再讀7,得到最終棧為1,3,6,7。最長遞增子串行為長度4。
這道題顯然是用第二種演算法(1 <= n <= 50w),**如下:
#include<
stdio.h
>
#define
n 500005
intnum[n], dp[n]; //這邊初始化dp 自己認為dp裡面是1 2 3 4 5 6 7 8 9 .....50005
intfind(
intlow,
inthigh,
inti)
//二分法查詢 確定num[i]的位置
return
low;
//返回其位置 返回不大於num【i】的 最小座標
}int
main()
dp[1] =
num[
1];
len =1
;for
(i =
2; i
<=
n; i
++) //從第二個貧窮城市的選擇開始
if(len ==1
) printf(
"case %d:\nmy king, at most %d road can be built.\n\n",
++case, len);
else
printf(
"case %d:\nmy king, at most %d roads can be built.\n\n",
++case, len);
}return0;
}
終於用到了fflush
今天遇到一 怪事 程式正常輸出幾千條log資訊,能全部輸出,但是通過重定向到乙個檔案中時總是少那麼幾十條,嘗試了輸出 2000,3000條結果差不多。後來小吳告訴我說是行緩衝的問題,果然如此,加上個fflush 就行了。為什麼會遇到這個問題?1.我們希望實現isakmp的橢圓曲線金鑰交換,因此需要先...
終於用到了DevCpp
幾天前就收到到了小菜給我發短訊息,不好意思,今天才拿出來看。不是我人品問題 輕易得相信狒狒 的確,在關於it方面,我們在校的學生得和狒狒們多交流,畢竟他們在工作了。來自xiaocai0001 c primer 我還沒有完整的看過,只是掃過幾眼.現在的編譯器不外有幾種,一種gcc系列的,像linux自...
我終於用到了泛型
我終於用到了泛型 左直拳 泛型是。net2。0出現的新東西。慚愧,3。0已經出了很久了,可我現在才開始用。落後啊落後,簡直屎一堆。delegate void setenablecallback system.windows.forms.control objctrl,bool enable 宣告 p...