4

我有一个充满随机整数的随机长度数组。为简单起见,它们按从高到低的顺序排列。

我也有一个目标随机整数。

我需要在不使用不必要的数字的情况下获得总和大于或等于目标的所有组合。给定这个例子:

nums = [10, 6, 5, 3, 2, 1, 1]

target = 8

我想要这个输出:

10 (10 is higher or equal to 8, so there's no need to sum it)

6+5

6+3

6+2

6+1+1

5+3

5+2+1

5+2+1 (Note that this result is different from the previous since there are 2 1s)

我尝试了很多递归策略,但我找不到正确的答案。不需要特定的语言,欢迎使用伪代码。

编辑:发布代码

private static boolean filtrar(final CopyOnWriteArrayList<Padre> padres) {
        if (sum(padres) < TARGET) {
            return false;
        }
        int i;
        for (i = padres.size(); i >= 0; i--) {
            if (!filtrar(copiaPadresSinElemento(padres, i-1))) {
                break;
            }
        }
        // Solución óptima, no se puede quitar nada.
        if (i == padres.size()) {
            print(padres);
        }
        return true;
    }

    private static int sum(final CopyOnWriteArrayList<Padre> padres) {
        int i = 0;
        for (final Padre padre : padres) {
            i += padre.plazas;
        }
        return i;
    }

    private static void print(final CopyOnWriteArrayList<Padre> padres) {
        final StringBuilder sb = new StringBuilder();
        for (final Padre padre : padres) {
            sb.append(padre);
            sb.append(", ");
        }
        final String str = sb.toString();
        System.out.println(str);
    }

    private static CopyOnWriteArrayList<Padre> copiaPadresSinElemento(
            final CopyOnWriteArrayList<Padre> padres, final int i) {
        final CopyOnWriteArrayList<Padre> copia = new CopyOnWriteArrayList<Padre>();
        for (int e = 0; e < padres.size(); e++) {
            if (e != i) {
                copia.add(padres.get(e));
            }
        }
        return copia;
    }

Padre 是一个简单的对象,其中包含每个数字的名称。Padre.plazas 是数字。

现在的数组是 [6,4,4,4,3,3,3],目标是 8。

4

2 回答 2

3

我认为这样的事情会起作用:

function filter(array, target): Boolean{ //assumes array is sorted in descending order
  if(sum(array) < target) return false;
  for(i = array.length-1; i>=0; --i){
    if(! filter(array.createCopyRemovingElementAt(i), target)) break;
  }
  if(i==array.length-1) print(array); // solution is "optimal": could not remove a single number
  return true;
}
于 2012-10-17T08:50:26.643 回答
1

一个低效的解决方案:复杂度 = O((2^n)*n)

for i = 0 to 2^size-of-array
do
   sum = 0
   for j = 0 to n-1
   do
     if(jth bit in i is 1)
     then
      sum+=array[j]
      fi
   done

  if(sum>=target)
     print the number i (uniquely identifies the set of numbers)
done
于 2012-10-17T08:59:48.183 回答