Considera la seguente dichiarazione del problema:
Dato un numero iniziale, tu e il tuo amico vi alternate per sottrarre un quadrato perfetto da esso. Vince il primo a raggiungere lo zero. Per esempio:
Stato iniziale: 37
Il giocatore 1 sottrae 16. Stato: 21
Player2 sottrae 8. Stato: 13
Il giocatore 1 sottrae 4. Stato: 9
Il giocatore 2 sottrae 9. Stato: 0
Player2 vince!
Scrivi un programma che, dato uno stato iniziale, restituisca una mossa ottimale, ovvero una mossa che garantisca la vittoria del gioco. Se nessuna mossa possibile può portarti a uno stato vincente, ritorna -1.
Questo problema può essere risolto in tempi pseudo-polinomiali usando la programmazione dinamica. L'idea è semplicemente riempire un array di lunghezza n (dove n è lo stato iniziale) dal basso verso l'alto con le mosse ottimali, o -1 se nessuna mossa porta alla vittoria. Questo richiederebbe O (n * sqrt (n)) poiché per ogni numero dobbiamo considerare di sottrarre ogni possibile quadrato perfetto più piccolo di esso (ce ne sono ~ sqrt (n)). Tuttavia, si tratta di una complessità di runtime pseudo-polinomiale poiché il runtime si ridimensiona in modo esponenziale in relazione alla dimensione dell'input in binario (numero di bit utilizzati per rappresentare il numero).
Qualcuno può pensare a un algoritmo polinomiale per risolvere questo problema? In caso contrario, potrebbe essere NP-Complete? Perché?