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 に答える