Considere la siguiente declaración del problema:
Dado un número inicial, usted y su amigo se turnan para restarle un cuadrado perfecto. El primero en llegar a cero gana. Por ejemplo:
Estado inicial: 37
El jugador1 resta 16. Estado: 21
El jugador2 resta 8. Estado: 13
El jugador1 resta 4. Estado: 9
El jugador2 resta 9. Estado: 0
¡Player2 gana!
Escriba un programa que, dado un estado inicial, devuelva un movimiento óptimo, es decir, uno que garantice conducir a ganar el juego. Si ningún movimiento posible puede llevarlo a un estado ganador, devuelva -1.
Este problema se puede resolver en tiempo pseudo-polinomial usando programación dinámica. La idea es simplemente llenar una matriz de longitud n (donde n es el estado inicial) de abajo hacia arriba con los movimientos óptimos, o -1 si ningún movimiento lleva a ganar. Esto tomaría O (n * sqrt (n)) ya que para cada número debemos considerar restar cada posible cuadrado perfecto más pequeño que él (hay ~ sqrt (n) de ellos). Sin embargo, esta es una complejidad de tiempo de ejecución pseudo-polinomial ya que el tiempo de ejecución en realidad se escala exponencialmente con relación al tamaño de la entrada en binario (# de bits utilizados para representar el número).
¿Alguien puede pensar en un algoritmo polinomial para resolver este problema? Si no, ¿podría ser NP-Complete? ¿Por qué?