我有一组整数.我想使用动态编程找到该集合中增长最长的子序列.
algorithm computer-science memoization dynamic-programming lis
你会得到一
n对数字.在每对中,第一个数字总是小于第二个数字.当且仅当小于时,一对(c,d)可以跟随.可以以这种方式形成对的链.找到形成的最长链对.(a,b)bc
我在接受亚马逊采访时得到了这个问题,但无法找到答案,只是它与LIS问题有关.
我正在练习算法,我的任务之一是计算给定0 <n <= 10 ^ 6个数字的所有最长增长子序列的数量.解决方案O(n ^ 2)不是一个选项.
我已经实现了查找LIS及其长度(LIS算法),但是该算法将数字切换到尽可能低的数字.因此,我不可能确定具有先前数字(较大的数字)的子序列是否能够实现最长的长度,否则我可以计算这些开关.
任何关于如何在O(nlogn)中得到这个的想法?我知道它应该使用动态编程来解决.
我实现了一个解决方案,它运行良好,但它需要两个嵌套循环(i in 1..n)x(j in 1..i-1).
所以它是O(n ^ 2)我认为,但它太慢了.
我试图甚至那些从数字阵列移动到一个二叉树(因为在每次我迭代i寻找所有更小的数字,然后数[I] -经历元件I-1..1),但它是更慢.
示例测试:
1 3 2 2 4
result: 3 (1,3,4 | 1,2,4 | 1,2,4)
3 2 1
result: 3 (1 | 2 | 3)
16 5 8 6 1 10 5 2 15 3 2 4 1
result: 3 (5,8,10,15 | 5,6,10,15 …Run Code Online (Sandbox Code Playgroud) 我有以下运行良好的算法
我尝试在这里为自己解释http://nemo.la/?p=943,并在这里解释http://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/以及 stackoverflow 上
我想修改它以产生最长的非单调递增子序列
对于序列 30 20 20 10 10 10 10
答案应该是 4:“10 10 10 10”
但是该算法的 nlgn 版本不起作用。初始化 s 以包含第一个元素“30”,并从第二个元素 = 20 开始。将发生以下情况:
第一步:30不大于等于20,我们找到大于20的最小元素,新的s变成“20”
第二步:20大于或等于20。我们扩展序列,s现在包含“20 20”
第三步:10不大于等于20。我们找到大于10的最小元素,即“20”。新的 s 变为“10 20”
此后 s 将永远不会增长,算法将返回 2 而不是 4
int height[100];
int s[100];
int binary_search(int first, int last, int x) {
int mid;
while (first < last) {
mid = (first + last) / 2;
if (height[s[mid]] == x)
return mid;
else if (height[s[mid]] >= x) …Run Code Online (Sandbox Code Playgroud) 我在阅读了Longest increase subsequence with K exceptions allowed之后创建了这个线程。我意识到,谁问这个问题的人并没有真正理解这个问题,因为他指的是一个链接解决了“最长递增子阵列与一个变化允许”的问题。所以他得到的答案实际上与 LIS 问题无关。
假设数组A 的长度为N。找出最长的递增子序列,允许有K 个例外。
示例
1) N=9 , K=1
A=[3,9,4,5,8,6,1,3,7]
答案:7
解释:
最长递增子序列是:3,4,5,8(或6),1(exception),3,7 -> total=7
2) N=11 , K=2
A=[5,6,4,7,3,9,2,5,1,8,7]
答案:8
如果 K=1,则只允许一种例外情况。如果使用已知的计算O(NlogN) 中最长递增子序列的算法(单击此处查看此算法),那么我们可以为数组的每个元素计算从 A[0] 到 A[N-1] 的 LIS A. 我们将结果保存在大小为N的新数组L 中。查看示例 n.1,L 数组将是: L=[1,2,2,3,4,4,4,4,5]。
使用反向逻辑,我们计算数组R,其中的每个元素都包含当前从 N-1 到 0 的最长递减序列。
除了一个例外,LIS 只是sol=max(sol,L[i]+R[i+1]), 其中sol被初始化为 …
我试图理解算法,它给出了时间O(n k log(n))中数组中长度K的增加子序列的数量.我知道如何使用O(k*n ^ 2)算法解决同样的问题.我查了一下,发现这个解决方案使用了BIT(Fenwick Tree)和DP.我也找到了一些代码,但我无法理解它.
以下是我访问过的一些有用的链接.
如果有人能帮助我理解这个算法,我真的很感激.
我实现了最长增加子序列(LIS)算法,因为我认为它会起作用,但结果完全是混乱的.
def lis():
#D = map(int, raw_input().split())
D = [3, 2, 6, 4, 5, 1]
L = [[] for i in range(len(D))]
L[0].append(D[0])
for i in range(len(D)):
for j in range(0,i):
if D[i] > D[j]:
L[i] = L[j]
L[i].append(D[i])
print L
Run Code Online (Sandbox Code Playgroud)
返回结果:
[[3], [2, 6, 4, 5], [2, 6, 4, 5], [2, 6, 4, 5], [2, 6, 4, 5], [1]]
Run Code Online (Sandbox Code Playgroud)
应该是什么:
[[3], [2], [2, 6], [2, 4], [2, 4, 5], [1]]
Run Code Online (Sandbox Code Playgroud)
正如我在调试器中看到的那样:
L[i] = L[j]
Run Code Online (Sandbox Code Playgroud)
不仅L[i]获得新值 …
计算数组中的 LIS(最长递增子序列)是一个非常著名的动态规划问题。然而,在每个教程中,他们首先展示了不使用 DP 概念的递归解决方案,然后通过应用自底向上 DP(迭代解决方案)来解决它。
我的问题是:
我们将如何在 递归解决方案本身中使用记忆化。不只是记忆,而是使用一维数组记忆。
我做了一些研究,但找不到任何相关的东西。虽然有 2 个地方要求递归记忆1和 2但那边的解决方案是使用 2D Map / Array 进行记忆。
无论如何,用一维数组记住解决方案,会给出错误的输出。这是我所做的:
int lis(int idx, int prev)
{
if(idx >= N)
return 0;
if(dp[idx])
return dp[idx];
int best_ans = lis(idx+1, prev);
int cur_ans = 0;
if(arr[idx] > prev)
{
cur_ans = 1 + lis(idx+1, arr[idx]);
}
int ans = max(best_ans, cur_ans);
dp[idx] = ans;
return ans;
}
int main()
{
// Scan …Run Code Online (Sandbox Code Playgroud) 我试图找到一个数组的所有最长的增加子序列.我可以设法在维基百科上O(n log n)建议使用二进制搜索找到一个这样的LIS .
有人可以帮助我,我怎样才能找到所有这样的LIS.我找不到更好的方法来做到这一点O(n²).任何优化建议都会非常有用.
我最近在hyper-v上创建了一个全新的gen 2虚拟机,并安装了最近发布的ubuntu 14.04版本.
即使在apt-get更新之后,在启动时,我的Windows Server 2012 R2 Hyper-V服务器也会抱怨hyper-v事件日志中的下层驱动程序
合成显示驱动程序:'Dev Ubuntu 14.04 Gen2'中的设备'Microsoft Synthetic Display Controller'已加载但与服务器版本不同.服务器版本3.3客户端版本3.2(虚拟机ID 9FC171E7-B2C6-4BD2-9FF0-253209B2A69D).设备可以使用,但这是一种不受支持的配置.这意味着在解决此问题之前不会提供技术支持.要解决此问题,请升级集成服务.要升级,请连接到虚拟机,然后从"操作"菜单中选择"插入Integration Services安装盘".(当然这似乎不起作用)
和
数据交换集成服务:Hyper-V数据交换连接到虚拟机'Dev Ubuntu 14.04 Gen2',但版本与Hyper-V预期的版本不匹配(虚拟机ID 9FC171E7-B2C6-4BD2-9FF0-253209B2A69D).框架版本:谈判(3.0) - 预期(3.0); 消息版本:谈判(4.0) - 预期(5.0).这是一种不受支持的配置.这意味着在解决此问题之前不会提供技术支持.要解决此问题,请升级集成服务.要升级,请连接到虚拟机,然后从"操作"菜单中选择"插入Integration Services安装磁盘"(类似地,这似乎不起作用).
此外,hyper-v在使用Windows 2012 R2 hyper-V Manager的Summary选项卡中抱怨"Integration Services:需要更新".
我的(显然是错误的)信念是Linux Integration Services已经集成到内核中,因此Trusty将与2012 R2 hyper-v服务兼容.
任何人都可以解释在何处/如何获取14.04更新的Integration Services包和正确的安装过程,以便使用hyper-v 2012 r2完全支持我的ubuntu虚拟机?
非常感谢你的帮助,Doug Coleman
std::lower_bound和函数的复杂度是多少std::upper_bound。
我知道万一std::set<int>是这样log(n),但我不知道std::vector<int>。
我正在使用向量 和 来实现最长递增子序列std::lower_bound。
这段代码的复杂度是多少?
int LIS2(vector<int> a) {
vector<int> v;
for (int i = 0; i < a.size(); i++) {
auto it = lower_bound(v.begin(), v.end(), a[i]);
if (it != v.end())
*it = a[i];
else
v.push_back(a[i]);
}
return v.size();
}
Run Code Online (Sandbox Code Playgroud) lis ×12
algorithm ×10
c++ ×2
memoization ×2
arrays ×1
fenwick-tree ×1
greedy ×1
hyper-v ×1
list ×1
lower-bound ×1
numbers ×1
python ×1
recursion ×1
stdvector ×1
subsequence ×1
ubuntu-14.04 ×1
upperbound ×1