0

这就是问题所在。

将给定数字 N 写为给定数字的总和,仅使用加法和减法。

这是一个例子:

N = 20
Integers = 8, 15, 2, 9, 10

20 = 8 + 15 - 2 + 9 - 10。

这是我的想法;

第一个想法是使用蛮力,交替加减。首先,我计算组合的数量及其 2^k(其中 k 是整数的数量),因为我只能交替使用减号和加号。然后我遍历从 1 到 2^k 的所有数字,并将其转换为二进制形式。对于任何 1,我使用加号,对于任何 0,我使用减号。通过示例(使用上面的示例),您会更容易。

The number of combinations is: 2^k = 2^5 = 32.
Now I run through all numbers from 1 to 32. 
So i get: 1=00001, that means: -8-15-2-9+10 = -24 This is false so I go on.
2 = 00010, which means: -8-15-2+9-10 = -26. Also false.

这种方法效果很好,但是当整数数量太大时,它需要的时间太长。

这是我在 C++ 中的代码:

#include <iostream>
#include <cmath>
using namespace std;
int convertToBinary(int number) {
    int remainder;
    int binNumber = 0;
    int i = 1;
    while(number!=0)
    {
        remainder=number%2;
        binNumber=binNumber + (i*remainder);
        number=number/2;
        i=i*10;
    }
    return binNumber;
}
int main()
{
    int N, numberOfIntegers, Combinations, Binary, Remainder, Sum;
    cin >> N >> numberOfIntegers;
    int Integers[numberOfIntegers];
    for(int i = 0; i<numberOfIntegers; i++)
    {
        cin >>Integers[i];
    }
    Combinations = pow(2.00, numberOfIntegers);
    for(int i = Combinations-1; i>=Combinations/2; i--) // I use half of the combinations, because 10100 will compute the same sum as 01011, but in with opposite sign.
    {
        Sum = 0;
        Binary = convertToBinary(i);
        for(int j = 0; Binary!=0; j++)
        {
            Remainder = Binary%10;
            Binary = Binary/10;
            if(Remainder==1)
            {
                Sum += Integers[numberOfIntegers-1-j];
            }
            else
            {
                Sum -= Integers[numberOfIntegers-1-j];
            }
        }
        if(N == abs(Sum))
        {
            Binary = convertToBinary(i);
            for(int j = 0; Binary!=0; j++)
            {
                Remainder = Binary%10;
                Binary = Binary/10;
                if(Sum>0)
                {
                    if(Remainder==1)
                    {
                        cout << "+" << Integers[numberOfIntegers-1-j];
                    }
                    else
                    {
                        cout << "-" << Integers[numberOfIntegers-1-j];
                    }
                }
                else
                {
                    if(Remainder==1)
                    {
                        cout << "-" << Integers[numberOfIntegers-1-j];
                    }
                    else
                    {
                        cout << "+" << Integers[numberOfIntegers-1-j];
                    }
                }
            }
            break;
        }
    }
    return 0;
}
4

3 回答 3

0

所以你担心的是你的复杂性。

让我们分析可以进行哪些优化。

给定 a[n] 中的 n 个数字和目标值 T;

可以肯定的是,加减法的一种组合会给你 T ;

所以 Sigma(m*a[k]) =T where( m =(-1 or 1) and 0 >= k >= n-1 )

这只是意味着..

它可以写成

(数组中一些数字的总和)=(数组中剩余数字的总和)+ T

就像你的情况一样..

8+15-2+9-10=20 可以写成

8+15+9= 20+10+2

所以包括目标在内的所有数字的总和 = 64 // 我们可以计算它.. :)

所以一半是32

如果进一步写为 20+(somthing)=32 在这种情况下为 12 (2+10)。

在这种情况下,您的问题可以简化为查找总和为 12 的数组中的数字

因此,您现在的问题可以减少为找到总和为 k 的数字组合(您可以按上述方式计算 k=12 。)对于其复杂性为 O(log (n )) n as size of array ,请保留请注意,您必须对数组进行排序并使用基于二进制搜索的算法来获取 O(log(n))。

因此,复杂性可以从 O(2^n) 到 O((N+1)logN),因为包括排序。

于 2013-03-28T20:16:15.787 回答
0

由于这是典型的作业,我不会给出完整的答案。但是考虑一下:

K = +a[1] - a[2] - a[3] + a[4]

可以改写为

a[0] = K
a[0] + a[2] + a[3] = a[1] + a[4]

您现在在两边都有正常的子集总和。

于 2013-03-28T12:33:51.810 回答
0

这需要您提供的静态输入,我使用核心 java 编写

  public static void main(String[] args) {

    System.out.println("Enter number");

    Scanner sc = new Scanner(System.in);

    int total = 0;

    while (sc.hasNext()) {


        int[] array = new int[5] ;

        for(int m=0;m<array.length;m++){
            array[m] = sc.nextInt();
        }

         int res =array[0];
            for(int i=0;i<array.length-1;i++){

                    if((array[i]%2)==1){
                            res = res - array[i+1];
                    }
                    else{
                    res =res+array[i+1];
                    }
            }
            System.out.println(res);
    }
}
于 2013-05-09T05:38:03.310 回答