Per costruire la risposta di awesomo ... se possiamo assumere che i numeri siano ordinati, possiamo fare meglio di O (n^k) per dato k; semplicemente prendi tutti i sottoinsiemi di dimensione O (n^(k-1)) (k-1), poi fai una ricerca binaria in quello che rimane per un numero che, aggiunto al primo (k-1), dà il bersaglio. Questo è O (n^(k-1) log n). Ciò significa che la complessità è certamente inferiore a quella.
Infatti, se sappiamo che la complessità è O (n^2) per k = 3, possiamo fare ancora meglio per k> 3: scegliere tutti i sottotitoli (k-3), di cui ci sono O (n^(k-3)), quindi risolvi il problema in O (n^2) sugli altri elementi. Questo è O (n^(k-1)) per k> = 3.
Tuttavia, forse si può fare anche meglio? Ci penserò su questo.
EDIT: Inizialmente aggiungevo un sacco di proposte su un problema diverso, ma ho deciso di pubblicare una versione ridotta. Incoraggio altri poster a vedere se credono che questa idea abbia qualche merito. L'analisi è dura, ma potrebbe essere abbastanza folle da funzionare.
Possiamo usare il fatto che abbiamo un k fisso e che le somme di numeri pari e dispari si comportano in certi modi, per definire un algoritmo ricorsivo per risolvere questo problema.
In primo luogo, modificare il problema in modo che si disponga di entrambi i numeri pari e dispari nell'elenco (questo può essere ottenuto dividendo per due se tutti sono pari, o sottraendo 1 da numeri ek dalla somma di destinazione se tutti sono dispari e ripetuti se necessario).
Successivamente, utilizzare il fatto che è possibile raggiungere anche somme di destinazione solo utilizzando un numero pari di numeri dispari, e le somme di destinazione dispari possono essere raggiunte utilizzando solo un numero dispari di numeri dispari. Generare sottoinsiemi appropriati dei numeri dispari e chiamare l'algoritmo in modo ricorsivo usando i numeri pari, la somma meno la somma del sottoinsieme di numeri dispari esaminati, e k meno la dimensione del sottoinsieme di numeri dispari. Quando k = 1, fai una ricerca binaria. Se mai k> n (non è sicuro che ciò possa accadere), restituisci falso.
Se si dispone di pochissimi numeri dispari, questo potrebbe consentire di acquisire rapidamente termini che devono far parte di un sottoinsieme vincente o scartare quelli che non possono. Puoi trasformare i problemi con molti numeri pari in problemi equivalenti con molti numeri dispari usando il trucco di sottrazione. Il caso peggiore deve quindi essere quando il numero di numeri pari e dispari è molto simile ... ed è qui che mi trovo in questo momento. Un limite superiore inutilmente allentato su questo è un numero di ordini di magnitudo peggiore di quello della forza bruta, ma credo che questo sia probabilmente almeno buono quanto la forza bruta. I pensieri sono ben accetti!
EDIT2: un esempio di quanto sopra, per illustrazione.
{1, 2, 2, 6, 7, 7, 20}, k = 3, sum = 20.
Subset {}:
{2, 2, 6, 20}, k = 3, sum = 20
= {1, 1, 3, 10}, k = 3, sum = 10
Subset {}:
{10}, k = 3, sum = 10
Failure
Subset {1, 1}:
{10}, k = 1, sum = 8
Failure
Subset {1, 3}:
{10}, k = 1, sum = 6
Failure
Subset {1, 7}:
{2, 2, 6, 20}, k = 1, sum = 12
Failure
Subset {7, 7}:
{2, 2, 6, 20}, k = 1, sum = 6
Success
Tecnicamente per 'k = 1' il limite inferiore sarebbe' O (n) '(non puoi assumere input ordinato) – awesomo
@awesomo Certo, se vuoi, ma assumendo che l'input sia ordinato non cambia il problema . – PengOne
vedere anche http://stackoverflow.com/questions/3684243/picking-five-numbers-that-sum-to-s/3687124 – sdcvvc