Module: incontrarsi nel mezzo


Problem

1 /5


Sottosuccessione massima del modulo

Theory Click to read/hide

Meet-in-the-middle
Meet-in-the-middle - un modo per ottimizzare soluzioni, che consiste nel suddividere il problema originale in due metà, risolverle ciascuna indipendentemente e quindi ottenere una soluzione al problema originale combinando le soluzioni delle metà.

Di conseguenza, ha senso usare meet-in-the-middle se sono soddisfatte due condizioni.
1) Il tempo necessario per risolvere metà del problema è asintoticamente inferiore al tempo necessario per risolvere l'intero problema.
2) Risolvendo semiproblemi, si possono ottenere soluzioni all'intero problema originale e, allo stesso tempo, asintoticamente più veloci rispetto alla semplice risoluzione dell'intero problema.
 
Esempio
Siano quattro array di numeri interi A, B, C e D. È necessario selezionare esattamente un numero da ciascun array in modo che la somma di questi numeri sia uguale a zero. Puoi usare una soluzione ingenua, ovvero enumerare semplicemente tutte le opzioni possibili. Funzionerà per O(n4).

Tuttavia, possiamo usare meet-in-the-middle.
Nota che a + b + c + d = 0 equivale a (a + b) = -(c + d).
Dividiamo il compito in due metà, vale a dire, nella prima metà useremo solo gli array A e B, e nella seconda metà solo C e D.
Iteriamo su tutte le possibili opzioni (a + b) nella prima metà e memorizziamo tutti i valori in una tabella hash (unordered_map, HashMap o simili. ). Funziona in O(n2).
Ora itereremo su tutte le possibili opzioni (c + d) nella seconda metà. Quando si considera una determinata opzione, verificheremo se esiste un valore nella tabella hash associato alla somma corrente del segno opposto (quindi abbiamo trovato due reciproci che si sommano a zero). Questa parte funziona anche in O(n2).
Non abbiamo una fase separata di "unione delle risposte" qui; in uno, lo abbiamo fatto durante la risoluzione di ciascuna delle due metà. La maggior parte delle attività avrà una situazione simile.
Abbiamo ottenuto una soluzione in O(n2) utilizzando meet-in-the-middle.

Vale la pena notare che meet-in-the-middle viene utilizzato più spesso durante l'ottimizzazione di soluzioni esponenziali, il che influisce in modo significativo sul tempo di esecuzione.

Problem

Dato un array A costituito da n interi positivi e un numero m. Seleziona la sequenza di posizioni B 1, B2, ..., Bk (1 <= B1 < B2 < ... < Bk <= n) tale che   ; \((\sum_{i=1}^{k} A_{B_i}) mod \; m\) era il massimo (ovvero , in modo che il resto della divisione della somma degli elementi della sottosequenza per il numero m sia il massimo possibile). La sequenza selezionata può essere vuota.
Calcola il valore massimo possibile di \((\sum_{i=1}^{k} A_{B_i}) mod \; m\).

Inserimento
La prima riga contiene due numeri interi n e m (1 <= n <= 35, 1 <= m <= 109). La seconda riga contiene n interi A1, A2< /code >, ..., LAn (1 <= LAi <= 109 )< br />
Impressum
Genera un numero: il valore massimo \((\sum_{i=1}^{k} A_{B_i}) mod \; m\)

 
Esempi
# Input Uscita
1 4 4
5 2 4 1
3
2 3 20
19941299
19
 
Spiegazioni
Nel primo esempio, puoi scegliere B = {1, 2}. (A1 + A2) mod m = (5 + 2) % 4 = 3.
Nel secondo esempio, puoi selezionare B = {3}.