除法列表两部分即它们的和彼此最靠近除法、它们的、两部分、最靠近

2023-09-10 23:33:03 作者:忘掉Ní゛我做不到っ

这是一个硬盘的算法问题:

将列表中的2份(金额),其最接近它们的和(多数)彼此

Divide the list in 2 parts (sum) that their sum closest to (most) each other

列表长度为1< = N< = 100和他们的(数字)的权重1和LT = W< = 250的问题给出

list length is 1 <= n <= 100 and their(numbers) weights 1<=w<=250 given in the question.

例如:23 65 134 32 95 123 34

For example : 23 65 134 32 95 123 34

1.sum = 256

1.sum = 256

2.sum = 250

2.sum = 250

1.list = 1 2 3 7

1.list = 1 2 3 7

2.list = 4 5 6

2.list = 4 5 6

我有一个算法,但它并没有对所有的输入工作。

I have an algorithm but it didn't work for all inputs.

初始化。列出的List1 = [],list2中= [] 排序元素(定列表)[23 32 34 65 95 123 134] 在弹出最后一个(最大的) 插入到不同,较少列表

执行: List1中= [],list2中= []

Implementation : list1 = [], list2 = []

选择134插入的List1。 List1中= [134] 选择123插入list2中。因为如果你插入到list1进行差别挺大 3.选择95和插入list2中。因为总和(list2中)+ 95 - 总和(List1中)小于

等等...

推荐答案

现在的问题是NPC,但有一个伪多项式算法的话,这是一个的 2分区的问题,你可以按照伪多项式时间算法的方式的子集之和的问题,解决这个问题。如果输入大小多项式与输入值,那么这可在多项式时间内完成。

The problem is NPC, but there is a pseudo polynomial algorithm for it, this is a 2-Partition problem, you can follow the way of pseudo polynomial time algorithm for sub set sum problem to solve this. If the input size is related polynomially to input values, then this can be done in polynomial time.

在你的情况(权重&LT; 250)是多项式(因为重量和LT = 250 N =>款项&LT; = 250 N ^ 2)。

In your case (weights < 250) it's polynomial (because weight <= 250 n => sums <= 250 n^2).

让总和=权重的总和,我们要创建二维数组A,然后构造A,逐列

Let Sum = sum of weights, we have to create two dimensional array A, then construct A, Column by Column

A [I,J] = true如果(j ==重量[I]或j - 重量[I] =体重[K](k是列表))。

A[i,j] = true if (j == weight[i] or j - weight[i] = weight[k] (k is in list)).

阵列与该算法创建需要为O(n ^ 2 *总和/ 2)。

The creation of array with this algorithm takes O(n^2 * sum/2).

最后,我们应该找到最有价值的列具有真正的价值。

At last we should find most valuable column which has true value.

下面是一个例子:

项:{0,1,2,3} 重量:{4,7,2,8} =>总和= 21总和/ 2 = 10

items:{0,1,2,3} weights:{4,7,2,8} => sum = 21 sum/2 = 10

items/weights 0|  1  | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10    
  --------------------------------------------------------- 
  |0             |  0  | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0
  |1             |  0  | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0
  |2             |  0  | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1
  |3             |  0  | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1

于是,因为[10,2] ==真分区是10,11

So because a[10, 2] == true the partition is 10, 11

这是一种算法,我发现这里和编辑一点点的来解决你的问题:

This is an algorithm I found here and edited a little bit to solve your problem:

bool partition( vector< int > C ) {
 // compute the total sum
 int n = C.size();
 int N = 0;
 for( int i = 0; i < n; i++ ) N += C[i];
 // initialize the table 
 T[0] = true;
 for( int i = 1; i <= N; i++ ) T[i] = false;
 // process the numbers one by one
 for( int i = 0; i < n; i++ )
  for( int j = N - C[i]; j >= 0; j--)
   if( T[j] ) T[j + C[i]] = true;

 for(int i = N/2;i>=0;i--)
    if (T[i])
      return i;
 return 0;
}

我刚刚回到第一个T [我],这是不是返回true T [N / 2](在最大到最小的顺序)。

I just returned first T[i] which is true instead of returning T[N/2] (in max to min order).

查找这使得这个值是并不难的路径。

Finding the path which gives this value is not hard.