找到连续的子序列,使得数字总和的多维数据集最多为y

时间:2014-02-22 08:48:47

标签: algorithm sequence dynamic-programming

我得到一系列数字A [1..n]和一个固定数字y。序列可能包含负值。 我的算法应该能够决定是否可以将序列划分为连续的子序列,使得每个子序列中的数字总和的立方体最多为y。这是我的初步答案:

enter image description here

我相信这个算法是合理的,但在继续进行记忆之前,我想听听你的意见。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

你的算法是正确的,但它是O(n ^ 2)而不是O(n)。

要改进它,您可以使用:

minsum([]) = 0
minsum(xs + [x]) = minsum(xs) + x if minsum(xs)^3 > y
                 = min(minsum(xs) + x, x) otherwise.

这会找到列表的一个分区,使得每个部分都有sum-cubed< = y,除了最后一个只有尽可能小的和。该函数返回分区最后一部分的最小总和。

这个问题的表达为您提供了一个迭代解决方案,您可以将其视为一种动态编程形式,因为步骤n中的解决方案取决于步骤n-1中的解决方案。

def exists_partition(xs, y):
   m = 0
   for x in xs:
       m = m + x if m**3 > y else min(m + x, x)
   return m**3 <= y

答案 1 :(得分:1)

根据您的描述,您显然不需要重复计算立方体。

相反,您可以计算y 的第3个根,然后将其传递给您的函数。

这是执行它的递归方式(尽管动态编程可能证明效率更高)。下面的解决方案假设输入序列只包含整数值,但可以很容易地转换为一系列有理值:

bool Partition(int values[],int numOfValues,int root3_y)
{
    for (int i=1; i<numOfValues; i++)
    {
        if (Partition(values,i,root3_y) && Partition(values+i,numOfValues-i,root3_y))
            return true;
    }
    int sum = 0;
    for (int i=0; i<numOfValues; i++)
        sum += values[i];
    return sum <= root3_y;
}