Algorithm 与数组最近的乘法值

Algorithm 与数组最近的乘法值,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我有一个整数数组,给定一个数字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, in

我有一个整数数组,给定一个数字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;
}
void findClosestValue(int arr[],int start,int end,int k,int&diff,int mul)
{

如果(开始这肯定是一个动态规划问题,但是有一些技巧

你需要建立一个表格,根据你能达到的产品,列出你第一次达到某个值时需要的最后一个因素的位置。(换句话说,如果你找到两种方法来达到某个值,你就要坚持第一种方法。)你用动态编程来建立这个表格

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

{
    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
。除以它,你就得到了
4
,位置
1
,位置
2
。除以它,你就得到了
2
位置
0
也就是2。最后你得到了
1
>开始时。(空产品始终为1。)

此解决方案几乎有效。问题是,您的表通常会变得非常大,并且几乎完全充满了过大的值。考虑到整数的约束,您应该跟踪您达到的最小绝对值,该值大于目标答案的绝对值。在这种情况下,w你的桌子应该放在下面:

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

这不是一个很大的胜利。但是对于更大的集合,这将提供一个巨大的改进。

这肯定是一个动态规划问题,但是有一些技巧

你需要建立一个表格,根据你能达到的产品,列出你第一次达到某个值时需要的最后一个因素的位置。(换句话说,如果你找到两种方法来达到某个值,你就要坚持第一种方法。)你用动态编程来建立这个表格

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

{
    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
。除以它,你就得到了
4
,位置
1
,位置
2
。除以它,你就得到了
2
位置
0
也就是2。最后你得到了
1
>开始时。(空产品始终为1。)

此解决方案几乎有效。问题是,您的表通常会变得非常大,并且几乎完全充满了过大的值。考虑到整数的约束,您应该跟踪您达到的最小绝对值,该值大于目标答案的绝对值。在这种情况下,w你的桌子应该放在下面:

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

这并不是一个很大的胜利。但是对于更大的集合,这将提供一个巨大的改进。

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