Optimal Strategy for the Divisor game using Dynamic Programming (original) (raw)

Last Updated : 22 Oct, 2025

Given an **integer N and two players, A and B are playing a game. On each player’s turn, that player makes a move by **subtracting a divisor of current N (which is less than N) from current N, thus **forming a new N for the next turn. The player who does not have any divisor left to subtract loses the game. The task is to tell which player wins the game if player A takes the first turn, assuming both players play optimally.

**Examples:

**Input : N = 2
**Output : Player A wins
**Explanation :
Player A chooses 1, and B has no more moves.

**Input : N = 3
**Output : Player B wins
**Explanation :
Player A chooses 1, player B chooses 1, and A has no more moves.

**Approach :
This problem mentioned above can be solved using **Dynamic Programming.

N -> current number left
A -> boolean value to decide if it's player A's turn or not

// C++ program for implementation of // Optimal Strategy for the Divisor // Game using Dynamic Programming #include <bits/stdc++.h> using namespace std;

// Recursive function to find the winner bool divisorGame(int N, bool A, int dp[][2]) {

// check if N=1 or N=3 then player B wins
if (N == 1 or N == 3)
    return false;

// check if N=2 then player A wins
if (N == 2)
    return true;

// check if current state already visited
// then return the previously obtained ans
if (dp[N][A] != -1)
    return dp[N][A];

// check if currently it is player A's turn
// then initialise the ans to 0
int ans = (A == 1) ? 0 : 1;

// Traversing across all the divisors of N
// which are less than N
for (int i = 1; i * i <= N; i++) {

    // check if current value of
    // i is a divisor of N
    if (N % i == 0) {

        // check if it is player A's turn
        // then we need at least one true
        if (A)
            ans |= divisorGame(N - i, 0, dp);

        // Else if it is player B's turn
        // then we need at least one false
        else
            ans &= divisorGame(N - i, 1, dp);
    }
}

// Return the current ans
return dp[N][A] = ans;

}

// Driver code int main() { // initialise N int N = 3;

int dp[N + 1][2];

memset(dp, -1, sizeof(dp));

if (divisorGame(N, 1, dp) == true)
    cout << "Player A wins";
else
    cout << "Player B wins";

return 0;

}

Java

// Java program for implementation of // optimal strategy for the divisor // game using dynamic programming

import java.util.*;

class GFG {

// Recursive function to find the winner
static int divisorGame(int N, int A, int dp[][]) {

    // Check if N = 1 or N = 3 then player B wins
    if (N == 1 || N == 3)
        return 0;

    // Check if N = 2 then player A wins
    if (N == 2)
        return 1;

    // Check if current state already visited
    // then return the previously obtained ans
    if (dp[N][A] != -1)
        return dp[N][A];

    // Check if currently it is player A's turn
    // then initialise the ans to 0
    int ans = (A == 1) ? 0 : 1;

    // Traversing across all the divisors of N
    // which are less than N
    for (int i = 1; i * i <= N; i++) {

        // Check if current value of
        // i is a divisor of N
        if (N % i == 0) {

            // Check if it is player A's turn
            // then we need at least one true
            if (A == 1)
                ans |= divisorGame(N - i, 0, dp);

            // Else if it is player B's turn
            // then we need at least one false
            else
               ans &= divisorGame(N - i, 1, dp);
        }
    }

    // Return the current ans
    return dp[N][A] = ans;
}

// Driver code
public static void main(String[] args) {
    
    // Initialise N
    int N = 3;

    int[][] dp = new int[N + 1][2];

    for (int i = 0; i < N + 1; i++) {
         for (int j = 0; j < 2; j++) {
              dp[i][j] = -1;
        }
    }

    if (divisorGame(N, 1, dp) == 1)
        System.out.print("Player A wins");
    else
        System.out.print("Player B wins");

}

}

// This code contributed by sapnasingh4991

Python3

Python3 program for implementation of

Optimal Strategy for the Divisor

Game using Dynamic Programming

from math import sqrt

Recursive function to find the winner

def divisorGame(N,A,dp): # check if N=1 or N=3 then player B wins if (N == 1 or N == 3): return False

# check if N=2 then player A wins
if (N == 2):
    return True

# check if current state already visited
# then return the previously obtained ans
if (dp[N][A] != -1):
    return dp[N][A]

# check if currently it is player A's turn
# then initialise the ans to 0
if(A == 1):
    ans = 0
else:
    ans = 1

# Traversing across all the divisors of N
# which are less than N
for i in range(1,int(sqrt(N))+1,1):
    # check if current value of
    # i is a divisor of N
    if (N % i == 0):
        # check if it is player A's turn
        # then we need at least one true
        if (A):
            ans |= divisorGame(N - i, 0, dp)

        # Else if it is player B's turn
        # then we need at least one false
        else:
            ans &= divisorGame(N - i, 1, dp) 

dp[N][A] = ans


# Return the current ans
return dp[N][A]

Driver code

if name == 'main': # initialise N N = 3

dp = [[-1 for i in range(2)] for j in range(N+1)]

if (divisorGame(N, 1, dp) == True):
    print("Player A wins")
else:
    print("Player B wins")

This code is contributed by Surendra_Gangwar

C#

// C# program for implementation of // optimal strategy for the divisor // game using dynamic programming using System;

class GFG {

// Recursive function to find the winner static int divisorGame(int N, int A, int [,]dp) {

// Check if N = 1 or N = 3 
// then player B wins
if (N == 1 || N == 3)
    return 0;

// Check if N = 2 then player A wins
if (N == 2)
    return 1;

// Check if current state already visited
// then return the previously obtained ans
if (dp[N, A] != -1)
    return dp[N, A];

// Check if currently it is player A's turn
// then initialise the ans to 0
int ans = (A == 1) ? 0 : 1;

// Traversing across all the divisors of N
// which are less than N
for(int i = 1; i * i <= N; i++)
{
    
   // Check if current value of
   // i is a divisor of N
   if (N % i == 0)
   {
       
       // Check if it is player A's turn
       // then we need at least one true
       if (A == 1)
           ans |= divisorGame(N - i, 0, dp);
           
       // Else if it is player B's turn
       // then we need at least one false
       else
          ans &= divisorGame(N - i, 1, dp);
   }
}

// Return the current ans
return dp[N, A] = ans;

}

// Driver code public static void Main(String[] args) {

// Initialise N
int N = 3;
int[,] dp = new int[N + 1, 2];

for(int i = 0; i < N + 1; i++) 
{
   for(int j = 0; j < 2; j++) 
   {
      dp[i, j] = -1;
   }
}

if (divisorGame(N, 1, dp) == 1)
{
    Console.Write("Player A wins");
}
else
{
    Console.Write("Player B wins");
}

} }

// This code is contributed by amal kumar choubey

JavaScript

`

**Time Complexity: O(N*log(N))
**Auxiliary Space: O(N)