【问题标题】:Closest multiplication value from array数组中最接近的乘法值
【发布时间】:2016-03-15 12:46:27
【问题描述】:

我有一个整数数组,并且给出了一个数字 K,我需要找到最接近 K 的值(也是数组的元素),这可以通过将数组中的各种数字相乘来生成。

例如。 arr - 2、2、5、5、7 K = 30

输出 - 2*2*7 = 28。

我想不出任何比指数解决方案更好的解决方案,我对元素进行不同的排列并检查最接近的值。请提出一种更好的(可能是动态编程)方法来有效地解决它。

这是我写的:-

void findClosestValue(int arr[], int start, int end, int k, int& diff, int mul)
{
    if(start<=end+1)
    {
        cout<<"  start = "<<start<<"  end = "<<end<<"  diff = "<<diff<<"  k = "<<k<<"  mul = "<<mul<<endl;
        if(diff > differ(k, mul))
            diff = differ(k, mul);
        findClosestValue(arr, start+1, end, k, diff, mul*arr[start]);
        findClosestValue(arr, start+1, end, k, diff, mul);
    }
    else
        return;
}

调用这个函数是:-

int val = 100000000;

findClosestValue(arr, 0, size-1, k, val, 1);

【问题讨论】:

  • 你应该提供你的工作细节(在代码中),然后有人可能会开始讨论如何改进它。
  • 我会给出提示的。您正在决定数字参与生成 K 的过程。每个数字都标记为 0 或 1,排列无关紧要。完整的搜索空间是 2^N,N 长度的数组。如果数组必须包含自然数,你可以从中暗示 2*2 必须小于 2*2*7,并且必须大于 2。这是家庭作业问题,你应该努力自己解决。
  • @Mai 您的提示与微不足道的指数解决方案有何不同?
  • 取对数可以看出它等价于子集和问题,因此是NP难的。
  • 这绝对是 NP 难的。可能有一个伪多项式解决方案,就像子集总和一样。

标签: algorithm dynamic-programming


【解决方案1】:

这绝对是一个动态规划问题,但是有一些技巧。

您需要建立一个表格,按您可以达到的产品,列出您第一次达到该值时需要的最后一个因素的位置。 (换句话说,如果你找到两种方法来达到一个值,你想坚持第一种。)你用动态规划建立这个表。

在您的[2, 2, 5, 5, 7] 示例中,位置从04,该表将如下所示:

{
    1: -1,
    2: 0,
    4: 1,
    5: 2,
    10: 2,
    20: 2,
    50: 3,
    100: 3,
    7: 4,
    14: 4,
    28: 4,
    35: 4,
    70: 4,
    140: 4,
    350: 4,
    700: 4
}

现在您在表格中搜索以找到最接近的值。这是28

现在你倒着读因子。你得到28 与位置4,即7。除以它,您在1 的位置有4,即2。除以它,你在0 的位置有2,即2。最后你在开始时有1。 (空乘始终为 1。)

此解决方案几乎有效。问题是您的表通常会变得非常大,并且几乎完全充满了太大的值。鉴于整数的约束,您应该跟踪您达到的最小绝对值,该绝对值大于目标答案的绝对值。在这种情况下,这将使您的表格保持不变:

{
    1: -1,
    2: 0,
    4: 1,
    5: 2,
    10: 2,
    20: 2,
    50: 3,
    7: 4,
    14: 4,
    28: 4,
    35: 4
}

这里没有那么大的胜利。但是对于更大的集合,这将提供显着的改进。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多