Count ways to reach a score with 3, 5 and 10

Last Updated : 1 May, 2026

Consider a game where players can score 3, 5, or 10 points in a move. Given a total score of n, the task is to find the number of ways to reach the given score.

Examples: 

Input: n = 20
Output: 4
Explanation: There are following 4 ways to reach 20: (10, 10), (5, 5, 10), (5, 5, 5, 5), (3, 3, 3, 3, 3, 5)

Input: n = 13
Output: 2
Explanation: There are following 2 ways to reach 13: (3, 5, 5), (3, 10)

Try It Yourself
redirect icon

The given problem is a variation of the coin change problem.

Using Recursion - O(2^n) Time and O(n) Space

The idea is to use a recursive function that explores all possible combinations of scoring points by making choices at each step. For each point value (3, 5, or 10), we have two options: either take that point value or skip it. The function will recursively explore these choices. When the total score reaches exactly 0, we count it as a valid combination and if it goes below 0, return 0.

Recurrence Relation: The final result will be the sum of both cases:

  • countWays(n, i, points) = countWays(n-points[i], i, points) + countWays(n, i+1, points)

Base Cases:

  • countWays(n) = 1, if n = 0.
  • countWays(n) = 0, if n < 0 or i == 3.
C++
// C++ program to find number of ways
// to reach a given score in a game.
#include <bits/stdc++.h>
using namespace std;

int countRecur(int n, int i, vector<int> &points) {
    
    // Base cases
    if (n==0) return 1;
    if (n<0 || i==3) return 0;
    
    // take points[i] point 
    int take = countRecur(n-points[i], i, points);
    
    // skip point 
    int noTake = countRecur(n, i+1, points);
    
    return take + noTake;
}

int countWays(int n) {
    
    vector<int> points = {3, 5, 10};
    return countRecur(n, 0, points);
}

int main() {
    int n = 20;
    cout << countWays(n);
    return 0;
}
Java
// Java program to find number of ways
// to reach a given score in a game.

import java.util.*;

class GfG {

    static int countRecur(int n, int i, int[] points) {
        
        // Base cases
        if (n == 0) return 1;
        if (n < 0 || i == 3) return 0;

        // take points[i] point 
        int take = countRecur(n - points[i], i, points);

        // skip point 
        int noTake = countRecur(n, i + 1, points);

        return take + noTake;
    }

    static int countWays(int n) {
        
        int[] points = {3, 5, 10};
        return countRecur(n, 0, points);
    }

    public static void main(String[] args) {
        int n = 20;
        System.out.println(countWays(n));
    }
}
Python
# Python program to find number of ways
# to reach a given score in a game.

def countRecur(n, i, points):
    
    # Base cases
    if n == 0:
        return 1
    if n < 0 or i == 3:
        return 0

    # take points[i] point 
    take = countRecur(n - points[i], i, points)

    # skip point 
    noTake = countRecur(n, i + 1, points)

    return take + noTake

def countWays(n):
    points = [3, 5, 10]
    return countRecur(n, 0, points)

if __name__ == "__main__":
    n = 20
    print(countWays(n))
C#
// C# program to find number of ways
// to reach a given score in a game.

using System;

class GfG {

    static int countRecur(int n, int i, int[] points) {
        
        // Base cases
        if (n == 0) return 1;
        if (n < 0 || i == 3) return 0;

        // take points[i] point 
        int take = countRecur(n - points[i], i, points);

        // skip point 
        int noTake = countRecur(n, i + 1, points);

        return take + noTake;
    }

    static int countWays(int n) {
        
        int[] points = {3, 5, 10};
        return countRecur(n, 0, points);
    }

    static void Main(string[] args) {
        int n = 20;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to find number of ways
// to reach a given score in a game.

function countRecur(n, i, points) {
    
    // Base cases
    if (n === 0) return 1;
    if (n < 0 || i === 3) return 0;

    // take points[i] point 
    let take = countRecur(n - points[i], i, points);

    // skip point 
    let noTake = countRecur(n, i + 1, points);

    return take + noTake;
}

function countWays(n) {
    let points = [3, 5, 10];
    return countRecur(n, 0, points);
}

let n = 20;
console.log(countWays(n));

Output
4

Using Top-Down DP (Memoization) - O(n) Time and O(n) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming:

1. Optimal Substructure: Number of ways to make score n at index i, i.e., countWays(n, i, points), depends on the optimal solutions of the subproblems countWays(n-points[i], i, points) and countWays(n, i+1, points). By combining these optimal substructures, we can efficiently calculate the number of ways to make target score at index i.

2. Overlapping Subproblems: While applying a recursive approach in this problem, we notice that certain subproblems are computed multiple times.

  • There are two parameters: n and i that changes in the recursive solution. So we create a 2D matrix of size (n+1)*3 for memoization.
  • We initialize this matrix as -1 to indicate nothing is computed initially.
  • Now we modify our recursive solution to first check if the value is -1, then only make recursive calls. This way, we avoid re-computations of the same subproblems.
C++
// C++ program to find number of ways
// to reach a given score in a game using memmoization
#include <bits/stdc++.h>
using namespace std;

int countRecur(int n, int i, vector<int> &points, 
               vector<vector<int>> &memo) {
    
    // Base cases
    if (n==0) return 1;
    if (n<0 || i==3) return 0;
    
    // If value is memoized
    if (memo[n][i]!=-1) {
        return memo[n][i];
    }
    
    // take points[i] point 
    int take = countRecur(n-points[i], i, points, memo);
    
    // skip point 
    int noTake = countRecur(n, i+1, points, memo);
    
    return memo[n][i] = take + noTake;
}

int countWays(int n) {
    
    vector<int> points = {3, 5, 10};
    vector<vector<int>> memo(n+1, vector<int>(3, -1));
    return countRecur(n, 0, points, memo);
}

int main() {
    int n = 20;
    cout << countWays(n);
    return 0;
}
Java
// Java program to find number of ways
// to reach a given score in a game using memmoization

import java.util.Arrays;

class GfG {

    static int countRecur(int n, int i, int[] points, int[][] memo) {
        
        // Base cases
        if (n == 0) return 1;
        if (n < 0 || i == 3) return 0;

        // If value is memoized
        if (memo[n][i] != -1) {
            return memo[n][i];
        }

        // take points[i] point 
        int take = countRecur(n - points[i], i, points, memo);

        // skip point 
        int noTake = countRecur(n, i + 1, points, memo);

        return memo[n][i] = take + noTake;
    }

    static int countWays(int n) {
        
        int[] points = {3, 5, 10};
        int[][] memo = new int[n + 1][3];
        for (int[] row : memo) {
            Arrays.fill(row, -1);
        }
        return countRecur(n, 0, points, memo);
    }

    public static void main(String[] args) {
        int n = 20;
        System.out.println(countWays(n));
    }
}
Python
# Python program to find number of ways
# to reach a given score in a game using memmoization

def countRecur(n, i, points, memo):
    
    # Base cases
    if n == 0:
        return 1
    if n < 0 or i == 3:
        return 0

    # If value is memoized
    if memo[n][i] != -1:
        return memo[n][i]

    # take points[i] point 
    take = countRecur(n - points[i], i, points, memo)

    # skip point 
    noTake = countRecur(n, i + 1, points, memo)

    memo[n][i] = take + noTake
    return memo[n][i]

def countWays(n):
    points = [3, 5, 10]
    memo = [[-1] * 3 for _ in range(n + 1)]
    return countRecur(n, 0, points, memo)

if __name__ == "__main__":
    n = 20
    print(countWays(n))
C#
// C# program to find number of ways
// to reach a given score in a game using memmoization

using System;

class GfG {

    static int countRecur(int n, int i, int[] points, int[,] memo) {
        
        // Base cases
        if (n == 0) return 1;
        if (n < 0 || i == 3) return 0;

        // If value is memoized
        if (memo[n, i] != -1) {
            return memo[n, i];
        }

        // take points[i] point 
        int take = countRecur(n - points[i], i, points, memo);

        // skip point 
        int noTake = countRecur(n, i + 1, points, memo);

        memo[n, i] = take + noTake;
        return memo[n, i];
    }

    static int countWays(int n) {
        
        int[] points = {3, 5, 10};
        int[,] memo = new int[n + 1, 3];
        for (int x = 0; x <= n; x++) {
            for (int y = 0; y < 3; y++) {
                memo[x, y] = -1;
            }
        }
        return countRecur(n, 0, points, memo);
    }

    static void Main(string[] args) {
        int n = 20;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to find number of ways
// to reach a given score in a game using memmoization

function countRecur(n, i, points, memo) {
    
    // Base cases
    if (n === 0) return 1;
    if (n < 0 || i === 3) return 0;

    // If value is memoized
    if (memo[n][i] !== -1) {
        return memo[n][i];
    }

    // take points[i] point 
    let take = countRecur(n - points[i], i, points, memo);

    // skip point 
    let noTake = countRecur(n, i + 1, points, memo);

    memo[n][i] = take + noTake;
    return memo[n][i];
}

function countWays(n) {
    let points = [3, 5, 10];
    let memo = Array.from({ length: n + 1 }, () => Array(3).fill(-1));
    return countRecur(n, 0, points, memo);
}

let n = 20;
console.log(countWays(n));

Output
4

Using Bottom-Up DP (Tabulation) - O(n) Time and O(n) Space

The idea is to fill the DP table based on previous values. For each point, we either include it or exclude it to compute the number of ways needed for each score. The table is filled in an iterative manner from score i = 1 to i = n and for each point points[j] from j=2 to j=0.

The dynamic programming relation is as follows: 

  • if (i-points[j]) is greater than 0, then dp[i][j] = dp[i-points[j]][j] + dp[i][j+1]
  • else dp[i][j] = dp[i][j+1].
C++
// C++ program to find number of ways
// to reach a given score in a game using tabulation
#include <bits/stdc++.h>
using namespace std;

int countWays(int n) {

    vector<int> points = {3, 5, 10};
    vector<vector<int>> dp(n + 1, vector<int>(4, 0));

    // Set 1 for score 0 for all points.
    for (int j = 0; j < 4; j++) {
        dp[0][j] = 1;
    }

    // Check for each score
    for (int i = 1; i <= n; i++) {

        // For each point.
        for (int j = 2; j >= 0; j--) {
            if (i - points[j] >= 0) {
                dp[i][j] = dp[i - points[j]][j] + dp[i][j + 1];
            }
            else {
                dp[i][j] = dp[i][j + 1];
            }
        }
    }

    return dp[n][0];
}

int main() {
  
    int n = 20;
    cout << countWays(n);
    return 0;
}
Java
// Java program to find number of ways
// to reach a given score in a game using tabulation

class GfG {

    static int countWays(int n) {
        
        int[] points = {3, 5, 10};
        int[][] dp = new int[n + 1][4];

        // Set 1 for score 0 for all points.
        for (int j = 0; j < 4; j++) {
            dp[0][j] = 1;
        }

        // Check for each score
        for (int i = 1; i <= n; i++) {
            
            // For each point.
            for (int j = 2; j >= 0; j--) {
                if (i - points[j] >= 0) {
                    dp[i][j] = dp[i - points[j]][j] + dp[i][j + 1];
                } else {
                    dp[i][j] = dp[i][j + 1];
                }
            }
        }

        return dp[n][0];
    }

    public static void main(String[] args) {
        int n = 20;
        System.out.println(countWays(n));
    }
}
Python
# Python program to find number of ways
# to reach a given score in a game using tabulation

def countWays(n):
    points = [3, 5, 10]
    dp = [[0] * 4 for _ in range(n + 1)]

    # Set 1 for score 0 for all points.
    for j in range(4):
        dp[0][j] = 1

    # Check for each score
    for i in range(1, n + 1):
        
        # For each point.
        for j in range(2, -1, -1):
            if i - points[j] >= 0:
                dp[i][j] = dp[i - points[j]][j] + dp[i][j + 1]
            else:
                dp[i][j] = dp[i][j + 1]

    return dp[n][0]

if __name__ == "__main__":
    n = 20
    print(countWays(n))
C#
// C# program to find number of ways
// to reach a given score in a game using tabulation

using System;

class GfG {

    static int countWays(int n) {
        
        int[] points = {3, 5, 10};
        int[,] dp = new int[n + 1, 4];

        // Set 1 for score 0 for all points.
        for (int j = 0; j < 4; j++) {
            dp[0, j] = 1;
        }

        // Check for each score
        for (int i = 1; i <= n; i++) {
            
            // For each point.
            for (int j = 2; j >= 0; j--) {
                if (i - points[j] >= 0) {
                    dp[i, j] = dp[i - points[j], j] + dp[i, j + 1];
                } else {
                    dp[i, j] = dp[i, j + 1];
                }
            }
        }

        return dp[n, 0];
    }

    static void Main(string[] args) {
        int n = 20;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to find number of ways
// to reach a given score in a game using tabulation

function countWays(n) {
    let points = [3, 5, 10];
    let dp = Array.from({ length: n + 1 }, () => Array(4).fill(0));

    // Set 1 for score 0 for all points.
    for (let j = 0; j < 4; j++) {
        dp[0][j] = 1;
    }

    // Check for each score
    for (let i = 1; i <= n; i++) {
        
        // For each point.
        for (let j = 2; j >= 0; j--) {
            if (i - points[j] >= 0) {
                dp[i][j] = dp[i - points[j]][j] + dp[i][j + 1];
            } else {
                dp[i][j] = dp[i][j + 1];
            }
        }
    }

    return dp[n][0];
}

let n = 20;
console.log(countWays(n));

Output
4

Using Space Optimized DP - O(n) Time and O(1) Space

In previous approach of dynamic programming we have derive the relation between states as given below:

  • if (i-points[j]) is greater than 0, then dp[i][j] = dp[i-points[j]][j] + dp[i][j+1]
  • else dp[i][j] = dp[i][j+1].

If we observe that for calculating current dp[i][j] state we only need to store the last 10 scores. There is no need to store all the previous states to compute result.

C++
// C++ program to find number of ways
// to reach a given score in a game using space optimised dp
#include <bits/stdc++.h>
using namespace std;

int countWays(int n) {

    vector<int> points = {3, 5, 10};

    // dp to store last 10 scores [-9, 0].
    vector<vector<int>> dp(10, vector<int>(4, 0));

    // Set ways=1 for score=0.
    for (int j = 0; j < 4; j++)
        dp[9][j] = 1;

    // Check for each score
    for (int i = 1; i <= n; i++) {
        vector<int> curr(4, 0);

        // For each point.
        for (int j = 2; j >= 0; j--) {
            curr[j] = dp[10 - points[j]][j] + curr[j + 1];
        }

        // Update dp states.
        for (int k = 0; k < 9; k++) {
            for (int j = 0; j < 4; j++) {
                dp[k][j] = dp[k + 1][j];
            }
        }
        for (int j = 0; j < 4; j++) {
            dp[9][j] = curr[j];
        }
    }

    return dp[9][0];
}

int main() {
    int n = 20;
    cout << countWays(n);
    return 0;
}
Java
// Java program to find number of ways
// to reach a given score in a game using space optimised dp

class GfG {

    static int countWays(int n) {

        int[] points = {3, 5, 10};
        
        // dp to store last 10 scores [-9, 0].
        int[][] dp = new int[10][4];
        
        // Set ways=1 for score=0.
        for (int j = 0; j < 4; j++) dp[9][j] = 1;

        // Check for each score
        for (int i = 1; i <= n; i++) {
            int[] curr = new int[4];
            
            // For each point.
            for (int j = 2; j >= 0; j--) {
                curr[j] = dp[10 - points[j]][j] + curr[j + 1];
            }

            // Update dp states.
            for (int k = 0; k < 9; k++) {
                for (int j = 0; j < 4; j++) {
                    dp[k][j] = dp[k + 1][j];
                }
            }
            for (int j = 0; j < 4; j++) {
                dp[9][j] = curr[j];
            }
        }

        return dp[9][0];
    }

    public static void main(String[] args) {
        int n = 20;
        System.out.println(countWays(n));
    }
}
Python
# Python program to find number of ways
# to reach a given score in a game using space optimised dp

def countWays(n):
    points = [3, 5, 10]
    
    # dp to store last 10 scores [-9, 0].
    dp = [[0] * 4 for _ in range(10)]
    
    # Set ways=1 for score=0.
    for j in range(4):
        dp[9][j] = 1

    # Check for each score
    for i in range(1, n + 1):
        curr = [0] * 4
        
        # For each point.
        for j in range(2, -1, -1):
            curr[j] = dp[10 - points[j]][j] + curr[j + 1]

        # Update dp states.
        for k in range(9):
            for j in range(4):
                dp[k][j] = dp[k + 1][j]
        for j in range(4):
            dp[9][j] = curr[j]

    return dp[9][0]

if __name__ == "__main__":
    n = 20
    print(countWays(n))
C#
// C# program to find number of ways
// to reach a given score in a game using space optimised dp

using System;

class GfG {

    static int countWays(int n) {
        int[] points = {3, 5, 10};
        
        // dp to store last 10 scores [-9, 0].
        int[,] dp = new int[10, 4];
        
        // Set ways=1 for score=0.
        for (int j = 0; j < 4; j++) dp[9, j] = 1;

        // Check for each score
        for (int i = 1; i <= n; i++) {
            int[] curr = new int[4];
            
            // For each point.
            for (int j = 2; j >= 0; j--) {
                curr[j] = dp[10 - points[j], j] + curr[j + 1];
            }

            // Update dp states.
            for (int k = 0; k < 9; k++) {
                for (int j = 0; j < 4; j++) {
                    dp[k, j] = dp[k + 1, j];
                }
            }
            for (int j = 0; j < 4; j++) {
                dp[9, j] = curr[j];
            }
        }

        return dp[9, 0];
    }

    static void Main(string[] args) {
        int n = 20;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to find number of ways
// to reach a given score in a game using space optimised dp

function countWays(n) {
    let points = [3, 5, 10];
    
    // dp to store last 10 scores [-9, 0].
    let dp = Array.from({ length: 10 }, () => Array(4).fill(0));
    
    // Set ways=1 for score=0.
    for (let j = 0; j < 4; j++) dp[9][j] = 1;

    // Check for each score
    for (let i = 1; i <= n; i++) {
        let curr = Array(4).fill(0);
        
        // For each point.
        for (let j = 2; j >= 0; j--) {
            curr[j] = dp[10 - points[j]][j] + curr[j + 1];
        }

        // Update dp states.
        for (let k = 0; k < 9; k++) {
            for (let j = 0; j < 4; j++) {
                dp[k][j] = dp[k + 1][j];
            }
        }
        for (let j = 0; j < 4; j++) {
            dp[9][j] = curr[j];
        }
    }

    return dp[9][0];
}

let n = 20;
console.log(countWays(n));

Output
4
Comment