2012-01-09 67 views
3

Longest Increasing Subsequence Problem如果我們重量改變長度即每個元素A 的長度爲1,如果我們將其更改至W 我們怎樣才能做到這一點在O(NlogN)。最大重量遞增子

對於實施例 對於8個元素

Elements 1 2 3 4 1 2 3 4 
Weights 10 20 30 40 15 15 15 50 

的最大重量爲110

我發現維基百科上的LIS解決方案,但我不能修改它來解決這個問題的陣列。

回答

4

儘管如此,我們仍然使用f[i]表示我們可以用E[i]以序列結束時獲得的最大值。

所以一般我們for (int i = 1;i <= n;i++) f[i] = dp(i);並初步f[0] = 0;E[0] = -INF;

現在,我們將在dp(i)O(log(N))計算f[i]

in dp(i),對於所有的0 <= j < i,我們將找到最大f[j]E[j] < E[i]。在這裏我們可以保持Segment Tree

所以dp(i) = find_max(1,E[i]-1) + W[i](這需要O(log)),並且對於已經計算的每個f [i],update(E[i],f[i])

所以整個算法需要(O(NlogN))

提示:如果E[i]在很大的範圍內變化,它可以是Discretization ed。

+0

什麼是DP [I]? 你可以請什麼將存儲在段樹? 謝謝。 – amahfouz 2015-07-07 09:40:16

+0

@amahfouz dp(i)只是計算f [i]值的函數。在分段樹中,索引(或範圍)是E的值,更新單個槽處的值,查詢範圍中的最大值,即典型分段樹。 – Topro 2015-07-26 07:32:33

+0

感謝您的回覆。 – amahfouz 2015-07-27 14:19:34

0

這裏是純粹的遞歸實施SWIFT:

// input is Array of (a,w), where a is element and w is weight 

func lisw(input: [(Int, Int)], index:Int = 0, largestA:Int? = nil)->Int{ 
     guard index < input.count else { return 0 } 

     let (a,w) = input[index] 

     if a <= largestA { 
      return lisw(input: input, index: index + 1, largestA: largestA) 
     } 

     let without_me = lisw(input: input, index: index + 1, largestA: largestA == nil ? a : largestA) 
     let with_me = lisw(input: input, index: index + 1, largestA: a) + w 

     return max(without_me,with_me) 
} 

隨意添加記憶化;)