在Longest Increasing Subsequence Problem中如果我们改变长度的重量,即每个元素的长度A i 是1,如果我们将其改为W i 我们怎样才能在O(NlogN)中做到这一点。
例如 对于8个元素的数组
Elements 1 2 3 4 1 2 3 4
Weights 10 20 30 40 15 15 15 50
最大重量为110。
我在维基百科上找到了LIS解决方案,但我无法对其进行修改以解决此问题。
答案 0 :(得分:4)
仍然,我们使用f[i]
表示序列以E[i]
结尾的最大值。
因此,我们通常会for (int i = 1;i <= n;i++) f[i] = dp(i);
,最初是f[0] = 0;
和E[0] = -INF;
现在我们将在f[i]
内的dp(i)
中计算O(log(N))
。
dp(i)
中的,我们会找到f[j]
的所有E[j] < E[i]
的最大0 <= j < 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
编辑。
答案 1 :(得分: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)
}
随意添加备忘录;)