有一个序列{a1,a2,a3,a4,..... aN}。运行是序列的最大严格增加或严格减少的连续部分。例如。如果我们有一个序列{1,2,3,4,7,6,5,2,3,4,1,2}我们有5个可能的运行{1,2,3,4,7},{7, 6,5,2},{2,3,4},{4,1}和{1,2}。
给定四个数字N,M,K,L。计算具有正好M次运行的N个数的可能序列的数量,序列中的每个数字小于或等于K,并且相邻数字之间的差异是小于等于
在采访中提出了这个问题。
我只能想到一个强力解决方案。 这个问题的有效解决方案是什么?
答案 0 :(得分:0)
使用动态编程。对于子串中的每个数字,保持最大增加和最大减少子序列的单独计数。当您以增量方式向末尾添加新数字时,可以使用这些计数来更新新数字的计数。复杂性:O(n ^ 2)
答案 1 :(得分:0)
这可以被重新定义为复发问题。将问题看作是找到#(N,M)(假设K和L是固定的,它们用于递归条件,因此相应地传播)。现在从更受限制的计数函数A(N,M; a)和D(N,M,a)开始,其中A计算具有最后一次运行递增的那些集合,D计算具有最后一次运行递减的那些,并且a是值集合中的最后一个元素。
以A(N,M; a)和D(N,M; a)表示#(N,M)(它是所有允许a的总和)。您可能会注意到两者之间存在关系(如反射A(N,M; a)= D(N,M; Ka))但除了速度表填充之外,这对计算无关紧要。
现在A(N,M; a)可以用A(N-1,M; w),A(N-1,M-1; x),D(N-1,M; y)和D(N-1,M-1; z)。我们的想法是,如果您从一组大小N-1开始并知道最后一次运行的方向和最后一个元素的值,您就知道添加元素a是添加到现有运行还是添加运行。因此,您可以计算从前一种情况的可能性中获得所需内容的可能方式的数量。
我会让你写下这个递归。请注意,这是您考虑L(仅加上符合L距离限制的那些)和K(寻找最终案例)的地方。
使用A(1,1; a)= 1,A(1,x> 1; a)= 0(以及类似于D)的事实终止递归。
现在,由于这是一个多次递归,请确保您的实现将结果存储在表中,然后尝试查找(通常称为动态编程)。
答案 2 :(得分:-1)
我想你的意思是'蛮力解决方案'我的意思是'直接解决方案涉及N,M,K,L'上的嵌套循环?有时直接的解决方案就足够了。直接解决方案足够好的一个原因是当您没有更好的解决方案时。另一个时候是数字不是很大。
随着我的胸部,我会反向写出循环,或类似的东西。我的意思是:
除非有人证明这是最有效的解决方案。