Considérez l'énoncé du problème suivant:
Étant donné un nombre initial, vous et votre ami, à tour de rôle, en soustrayez un carré parfait. Le premier à arriver à zéro gagne. Par exemple:
État initial: 37
Le joueur 1 soustrait 16. État: 21
Le joueur 2 soustrait 8. État: 13
Le joueur 1 soustrait 4. État: 9
Player2 soustrait 9. État: 0
Player2 gagne!
Écrivez un programme qui, étant donné un état initial, renvoie un coup optimal, c'est-à-dire un coup sûr qui mènera à la victoire. Si aucun mouvement possible ne peut vous mener à un état gagnant, renvoyez -1.
Ce problème peut être résolu en temps pseudo-polynomial en utilisant la programmation dynamique. L'idée consiste simplement à remplir un tableau de longueur n (où n est l'état initial) de bas en haut avec les mouvements optimaux, ou -1 si aucun mouvement ne mène à la victoire. Cela prendrait O (n * sqrt (n)) car pour chaque nombre, nous devons considérer la soustraction de chaque carré parfait possible plus petit que lui (il y en a ~ sqrt (n)). Cependant, il s'agit d'une complexité d'exécution pseudo-polynomiale, car l'exécution évolue en fait de manière exponentielle en fonction de la taille de l'entrée en binaire (nombre de bits utilisés pour représenter le nombre).
Quelqu'un peut-il penser à un algorithme polynomial pour résoudre ce problème? Sinon, pourrait-il être NP-Complete? Pourquoi?