Find ways an Integer can be expressed as sum of n-th power of unique natural numbers

Last Updated : 27 Sep, 2026

Given two integers n and x, find the number of ways to express n as the sum of the xth power of unique natural numbers.

Each natural number can be used at most once. Return the total number of ways modulo 109 + 7.

Examples : 

Input: n = 10, x = 2
Output: 1 
Explanation: 10 = 12 + 32, Hence total 1 possibility.

Input: n = 100, x = 2
Output: 3
Explanation: 100 = 102, 62 + 82 and 12 + 32 + 42 + 52 + 72 Hence total 3 possibilities.

Try It Yourself
redirect icon

Recursive Approach - Exponential Time and O(m) Space:

For each natural number, make two choices: either include its xth power in the sum or skip it. Recursively continue with the next number and the remaining sum.

  • Start with the first natural number 1 and the target sum n.
  • Calculate the xth power of the current number.
  • If the power is greater than the remaining sum, stop exploring this branch.
  • Otherwise, make two recursive calls: one by including the current power and another by skipping it.
  • When the remaining sum becomes 0, return 1 to count the current combination.
  • Add the results of both choices and take the result modulo 10^9 + 7.
C++
#include <iostream>
using namespace std;

const int MOD = 1e9 + 7;
int powerX;

// Recursive function to count ways to form n
// using unique powers starting from ind.
int solve(int n, int ind) {
    if (n == 0)
        return 1;

    int power = 1;

    // Calculate ind^x
    for (int i = 0; i < powerX; i++)
        power *= ind;

    // Current and all larger powers cannot be used
    if (power > n)
        return 0;

    // Choice 1: Do not take ind^x
    int notTake = solve(n, ind + 1);

    // Choice 2: Take ind^x
    int take = solve(n - power, ind + 1);

    return (take + notTake) % MOD;
}

int numOfWays(int n, int x) {
    powerX = x;
    return solve(n, 1);
}

int main() {
    // Input: n = 10, x = 2
    // Output: 1
    // Explanation: 10 = 1^2 + 3^2

    int n = 10, x = 2;

    cout << numOfWays(n, x);

    return 0;
}
Java
import java.util.*;

class GFG {
    static final int MOD = 1000000007;
    static int powerX;

    // Recursive function to count ways to form n
    // using unique powers starting from ind.
    static int solve(int n, int ind) {
        if (n == 0)
            return 1;

        int power = 1;

        // Calculate ind^x.
        for (int i = 0; i < powerX; i++)
            power *= ind;

        // Current and all larger powers cannot be used.
        if (power > n)
            return 0;

        // Choice 1: Do not take ind^x.
        int notTake = solve(n, ind + 1);

        // Choice 2: Take ind^x.
        int take = solve(n - power, ind + 1);

        return (take + notTake) % MOD;
    }

    static int numOfWays(int n, int x) {
        powerX = x;
        return solve(n, 1);
    }

    public static void main(String[] args) {
        // Input: n = 10, x = 2
        // Output: 1
        // Explanation: 10 = 1^2 + 3^2

        int n = 10;
        int x = 2;

        System.out.println(numOfWays(n, x));
    }
}
Python
class GFG:

    def power(self, num, n):
        if n == 0:
            return 1

        if n % 2 == 0:
            half = self.power(num, n // 2)
            return half * half

        half = self.power(num, n // 2)
        return num * half * half

    def checkRecursive(self, x, n, curr_num=1, curr_sum=0):

        results = 0

        # Calculate curr_num^n
        p = self.power(curr_num, n)

        while p + curr_sum < x:

            results += self.checkRecursive(
                x,
                n,
                curr_num + 1,
                curr_sum + p
            )

            curr_num += 1
            p = self.power(curr_num, n)

        # If sum of powers is equal to x
        if p + curr_sum == x:
            results += 1

        return results

    def numOfWays(self, n, x):
        return self.checkRecursive(n, x)
C#
using System;

public class GFG
{
    const int MOD = 1000000007;
    static int powerX;

    // Recursive function to count ways to form n
    // using unique powers starting from ind.
    static int solve(int n, int ind)
    {
        if (n == 0)
            return 1;

        int power = 1;

        // Calculate ind^x.
        for (int i = 0; i < powerX; i++)
            power *= ind;

        // Current and all larger powers cannot be used.
        if (power > n)
            return 0;

        // Choice 1: Do not take ind^x.
        int notTake = solve(n, ind + 1);

        // Choice 2: Take ind^x.
        int take = solve(n - power, ind + 1);

        return (take + notTake) % MOD;
    }

    static int numOfWays(int n, int x)
    {
        powerX = x;
        return solve(n, 1);
    }

    public static void Main()
    {
        // Input: n = 10, x = 2
        // Output: 1
        // Explanation: 10 = 1^2 + 3^2

        int n = 10;
        int x = 2;

        Console.WriteLine(numOfWays(n, x));
    }
}
JavaScript
class Solution {

    power(num, n) {
        if (n === 0)
            return 1;

        if (n % 2 === 0) {
            const half = this.power(num, Math.floor(n / 2));
            return half * half;
        }

        const half = this.power(num, Math.floor(n / 2));
        return num * half * half;
    }

    checkRecursive(x, n, curr_num = 1, curr_sum = 0) {

        let results = 0;

        // Calculate curr_num^n
        let p = this.power(curr_num, n);

        while (p + curr_sum < x) {

            results += this.checkRecursive(
                x,
                n,
                curr_num + 1,
                curr_sum + p
            );

            curr_num++;
            p = this.power(curr_num, n);
        }

        // If sum of powers is equal to x
        if (p + curr_sum === x)
            results++;

        return results;
    }

    numOfWays(n, x) {
        return this.checkRecursive(n, x);
    }
}

Output
1

Memoization - O(n × m) Time and O(n × m) Space:

The recursive approach repeatedly solves the same subproblems.

To optimize we store the result for each combination of the remaining sum and the current natural number in a DP table.

  • Create a DP table where dp[sum][ind] stores the number of ways to form sum using numbers from ind onward.
  • Start the recursion with sum = n and ind = 1.
  • For every number, calculate its xth power.
  • Recursively calculate the number of ways by both skipping and taking the current power.
  • Store the result in dp[sum][ind] to avoid recomputing the same state.
  • Return the stored value whenever the same state is encountered again.
  • Take every result modulo 10^9 + 7.
C++
#include <iostream>
#include <vector>
using namespace std;

const int MOD = 1e9 + 7;
int powerX;

int solve(int n, int ind, vector<vector<int>>& dp) {
    if (n == 0)
        return 1;

    int power = 1;

    // Calculate ind^x
    for (int i = 0; i < powerX; i++)
        power *= ind;

    if (power > n)
        return 0;

    // Return the already computed result
    if (dp[n][ind] != -1)
        return dp[n][ind];

    // Do not take ind^x
    int notTake = solve(n, ind + 1, dp);

    // Take ind^x
    int take = solve(n - power, ind + 1, dp);

    return dp[n][ind] = (take + notTake) % MOD;
}

int numOfWays(int n, int x) {
    powerX = x;

    // Only values up to n are needed as indices.
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, -1));

    return solve(n, 1, dp);
}

int main() {
    // Input: n = 10, x = 2
    // Output: 1
    // Explanation: 10 = 1^2 + 3^2

    int n = 10, x = 2;

    cout << numOfWays(n, x);

    return 0;
}
Java
import java.util.*;

public class GFG {

    static final int MOD = 1000000007;
    static int powerX;

    static int solve(int n, int ind, int[][] dp) {
        if (n == 0)
            return 1;

        int power = 1;

        // Calculate ind^x
        for (int i = 0; i < powerX; i++)
            power *= ind;

        if (power > n)
            return 0;

        // Return the already computed result
        if (dp[n][ind] != -1)
            return dp[n][ind];

        // Do not take ind^x
        int notTake = solve(n, ind + 1, dp);

        // Take ind^x
        int take = solve(n - power, ind + 1, dp);

        return dp[n][ind] = (take + notTake) % MOD;
    }

    static int numOfWays(int n, int x) {
        powerX = x;

        int[][] dp = new int[n + 1][n + 1];

        for (int i = 0; i <= n; i++)
            Arrays.fill(dp[i], -1);

        return solve(n, 1, dp);
    }

    public static void main(String[] args) {
        int n = 10, x = 2;

        System.out.println(numOfWays(n, x));
    }
}
Python
def solve(n, ind, x, dp, mod):
    if n == 0:
        return 1

    power = 1

    # Calculate ind^x.
    for _ in range(x):
        power *= ind

    if power > n:
        return 0

    # Return the already computed result.
    if dp[n][ind] != -1:
        return dp[n][ind]

    # Do not take ind^x.
    notTake = solve(n, ind + 1, x, dp, mod)

    # Take ind^x.
    take = solve(n - power, ind + 1, x, dp, mod)

    dp[n][ind] = (take + notTake) % mod

    return dp[n][ind]


def numOfWays(n, x):
    mod = 10**9 + 7

    # Only values up to n are needed as indices.
    dp = [[-1] * (n + 1) for _ in range(n + 1)]

    return solve(n, 1, x, dp, mod)


if __name__ == "__main__":
    # Input: n = 10, x = 2
    # Output: 1
    # Explanation: 10 = 1^2 + 3^2

    n = 10
    x = 2

    print(numOfWays(n, x))
C#
using System;

public class GFG
{
    const int MOD = 1000000007;
    static int powerX;

    static int solve(int n, int ind, int[,] dp)
    {
        if (n == 0)
            return 1;

        int power = 1;

        // Calculate ind^x
        for (int i = 0; i < powerX; i++)
            power *= ind;

        if (power > n)
            return 0;

        // Return the already computed result
        if (dp[n, ind] != -1)
            return dp[n, ind];

        // Do not take ind^x
        int notTake = solve(n, ind + 1, dp);

        // Take ind^x
        int take = solve(n - power, ind + 1, dp);

        return dp[n, ind] = (take + notTake) % MOD;
    }

    static int numOfWays(int n, int x)
    {
        powerX = x;

        int[,] dp = new int[n + 1, n + 1];

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

        return solve(n, 1, dp);
    }

    public static void Main()
    {
        int n = 10, x = 2;

        Console.WriteLine(numOfWays(n, x));
    }
}
JavaScript
function solve(n, ind, x, dp, mod) {
    if (n === 0)
        return 1;

    let power = 1;

    // Calculate ind^x.
    for (let i = 0; i < x; i++)
        power *= ind;

    if (power > n)
        return 0;

    // Return the already computed result.
    if (dp[n][ind] !== -1)
        return dp[n][ind];

    // Do not take ind^x.
    const notTake = solve(n, ind + 1, x, dp, mod);

    // Take ind^x.
    const take = solve(n - power, ind + 1, x, dp, mod);

    dp[n][ind] = (take + notTake) % mod;

    return dp[n][ind];
}

function numOfWays(n, x) {
    const mod = 1000000007;

    // Only values up to n are needed as indices.
    const dp = Array.from(
        { length: n + 1 },
        () => new Array(n + 1).fill(-1)
    );

    return solve(n, 1, x, dp, mod);
}

// Driver Code
const n = 10;
const x = 2;

console.log(numOfWays(n, x));

Output
1

Bottom-Up DP - O(n × m) Time and O(n × m) Space:

The idea is to Convert the recursive decisions into an iterative DP removing the recursion overhead.

  • Let dp[s][i] represent the number of ways to form sum s using the first i natural numbers.
  • For each number, update the table by either excluding or including its xth power.
  • Find the largest natural number m such that m^x <= n.
  • Create a DP table of size (n + 1) × (m + 1).
  • Initialize dp[0][i] = 1, since there is one way to form sum 0: choose nothing.
  • For every natural number i, calculate i^x.
  • For every sum s, first carry forward the ways that do not use i^x.
  • If s >= i^x, add the ways obtained by including i^x, using dp[s - i^x][i - 1].
  • The final answer is dp[n][m].
C++
#include <iostream>
#include <vector>
using namespace std;

const int MOD = 1e9 + 7;

int numOfWays(int n, int x) {
    int maxNum = 0;
    int power = 1;

    // Find the largest number whose xth power is <= n
    while (true) {
        maxNum++;

        power = 1;
        for (int j = 0; j < x; j++)
            power *= maxNum;

        if (power > n) {
            maxNum--;
            break;
        }
    }

    // dp[sum][i] = ways to form sum using numbers 1...i
    vector<vector<int>> dp(n + 1, vector<int>(maxNum + 1, 0));

    // There is one way to form sum 0: choose nothing.
    for (int i = 0; i <= maxNum; i++)
        dp[0][i] = 1;

    for (int i = 1; i <= maxNum; i++) {
        int currPower = 1;

        // Calculate i^x
        for (int j = 0; j < x; j++)
            currPower *= i;

        for (int sum = 1; sum <= n; sum++) {
            // Do not use i^x
            dp[sum][i] = dp[sum][i - 1];

            // Use i^x if it does not exceed the current sum
            if (sum >= currPower) {
                dp[sum][i] =
                    (dp[sum][i] + dp[sum - currPower][i - 1]) % MOD;
            }
        }
    }

    return dp[n][maxNum];
}

int main() {
    // Input: n = 10, x = 2
    // Output: 1
    // Explanation: 10 = 1^2 + 3^2

    int n = 10, x = 2;

    cout << numOfWays(n, x);

    return 0;
}
Java
public class GFG {

    static final int MOD = 1000000007;

    static int numOfWays(int n, int x) {
        int maxNum = 0;
        int power = 1;

        // Find the largest number whose xth power is <= n
        while (true) {
            maxNum++;

            power = 1;
            for (int j = 0; j < x; j++)
                power *= maxNum;

            if (power > n) {
                maxNum--;
                break;
            }
        }

        // dp[sum][i] = ways to form sum using numbers 1...i
        int[][] dp = new int[n + 1][maxNum + 1];

        // There is one way to form sum 0: choose nothing.
        for (int i = 0; i <= maxNum; i++)
            dp[0][i] = 1;

        for (int i = 1; i <= maxNum; i++) {
            int currPower = 1;

            // Calculate i^x
            for (int j = 0; j < x; j++)
                currPower *= i;

            for (int sum = 1; sum <= n; sum++) {

                // Do not use i^x
                dp[sum][i] = dp[sum][i - 1];

                // Use i^x if it does not exceed the current sum
                if (sum >= currPower) {
                    dp[sum][i] =
                        (dp[sum][i] + dp[sum - currPower][i - 1]) % MOD;
                }
            }
        }

        return dp[n][maxNum];
    }

    public static void main(String[] args) {
        int n = 10, x = 2;

        System.out.println(numOfWays(n, x));
    }
}
Python
class GFG:
    def numOfWays(self, n, x):
        MOD = 1000000007

        maxNum = 0
        power = 1

        # Find the largest number whose xth power is <= n
        while True:
            maxNum += 1

            power = 1
            for j in range(x):
                power *= maxNum

            if power > n:
                maxNum -= 1
                break

        # dp[total][i] = ways to form total using numbers 1...i
        dp = [[0] * (maxNum + 1) for _ in range(n + 1)]

        # One way to form sum 0: choose no numbers.
        for i in range(maxNum + 1):
            dp[0][i] = 1

        for i in range(1, maxNum + 1):
            currPower = 1

            # Calculate i^x
            for j in range(x):
                currPower *= i

            for total in range(1, n + 1):

                # Do not use i^x
                dp[total][i] = dp[total][i - 1]

                # Use i^x if it does not exceed the current sum
                if total >= currPower:
                    dp[total][i] = (
                        dp[total][i] +
                        dp[total - currPower][i - 1]
                    ) % MOD

        return dp[n][maxNum]
C#
using System;

public class GFG
{
    const int MOD = 1000000007;

    static int numOfWays(int n, int x)
    {
        int maxNum = 0;
        int power = 1;

        // Find the largest number whose xth power is <= n
        while (true)
        {
            maxNum++;

            power = 1;
            for (int j = 0; j < x; j++)
                power *= maxNum;

            if (power > n)
            {
                maxNum--;
                break;
            }
        }

        // dp[sum][i] = ways to form sum using numbers 1...i
        int[,] dp = new int[n + 1, maxNum + 1];

        // There is one way to form sum 0: choose nothing.
        for (int i = 0; i <= maxNum; i++)
            dp[0, i] = 1;

        for (int i = 1; i <= maxNum; i++)
        {
            int currPower = 1;

            // Calculate i^x
            for (int j = 0; j < x; j++)
                currPower *= i;

            for (int sum = 1; sum <= n; sum++)
            {
                // Do not use i^x
                dp[sum, i] = dp[sum, i - 1];

                // Use i^x if it does not exceed the current sum
                if (sum >= currPower)
                {
                    dp[sum, i] =
                        (dp[sum, i] + dp[sum - currPower, i - 1]) % MOD;
                }
            }
        }

        return dp[n, maxNum];
    }

    public static void Main()
    {
        int n = 10, x = 2;

        Console.WriteLine(numOfWays(n, x));
    }
}
JavaScript
class GFG {
    numOfWays(n, x) {
        const MOD = 1000000007;

        let maxNum = 0;
        let power = 1;

        // Find the largest number whose xth power is <= n
        while (true) {
            maxNum++;

            power = 1;
            for (let j = 0; j < x; j++)
                power *= maxNum;

            if (power > n) {
                maxNum--;
                break;
            }
        }

        // dp[total][i] = ways to form total using numbers 1...i
        const dp = Array.from(
            { length: n + 1 },
            () => Array(maxNum + 1).fill(0)
        );

        // There is one way to form sum 0: choose nothing.
        for (let i = 0; i <= maxNum; i++)
            dp[0][i] = 1;

        for (let i = 1; i <= maxNum; i++) {
            let currPower = 1;

            // Calculate i^x
            for (let j = 0; j < x; j++)
                currPower *= i;

            for (let total = 1; total <= n; total++) {

                // Do not use i^x
                dp[total][i] = dp[total][i - 1];

                // Use i^x if it does not exceed the current sum
                if (total >= currPower) {
                    dp[total][i] =
                        (dp[total][i] +
                         dp[total - currPower][i - 1]) % MOD;
                }
            }
        }

        return dp[n][maxNum];
    }
}

Output
1

Space Optimized DP - O(n × m) Time and O(n) Space :

We can further reduce the space by observing that while processing a number, we only need the results from the previous set of numbers.

  • We can maintain a single array where dp[s] represents the number of ways to form sum s using the numbers processed so far.
  • Traverse the sums in reverse order so that each natural number is used at most once.

Follow the below steps to implement the idea:

  • Create a one-dimensional array dp of size n + 1.
  • Initialise dp[0] = 1.
  • For every natural number i whose xth power is at most n, calculate power = i^x.
  • Traverse sum from n down to power.
  • Update dp[sum] using: dp[sum] += dp[sum - power]
  • Take the result modulo 10^9 + 7.
  • The reverse traversal ensures that the same i^x is not used more than once.
  • Return dp[n].
C++
#include <iostream>
#include <vector>
using namespace std;

const int MOD = 1e9 + 7;

int numOfWays(int n, int x) {
    vector<int> dp(n + 1, 0);

    // One way to form sum 0: choose no numbers.
    dp[0] = 1;

    for (int num = 1; ; num++) {
        int power = 1;

        // Calculate num^x
        for (int j = 0; j < x; j++)
            power *= num;

        // No larger number can contribute if num^x > n
        if (power > n)
            break;

        // Traverse backwards so that num^x is used at most once.
        for (int sum = n; sum >= power; sum--) {
            dp[sum] = (dp[sum] + dp[sum - power]) % MOD;
        }
    }

    return dp[n];
}

int main() {
    // Input: n = 10, x = 2
    // Output: 1
    // Explanation: 10 = 1^2 + 3^2

    int n = 10, x = 2;

    cout << numOfWays(n, x);

    return 0;
}
Java
public class GFG {

    static final int MOD = 1000000007;

    static int numOfWays(int n, int x) {
        int[] dp = new int[n + 1];

        // One way to form sum 0: choose no numbers.
        dp[0] = 1;

        for (int num = 1; ; num++) {
            int power = 1;

            // Calculate num^x
            for (int j = 0; j < x; j++)
                power *= num;

            // No larger number can contribute if num^x > n
            if (power > n)
                break;

            // Traverse backwards so that num^x is used at most once.
            for (int sum = n; sum >= power; sum--) {
                dp[sum] = (dp[sum] + dp[sum - power]) % MOD;
            }
        }

        return dp[n];
    }

    public static void main(String[] args) {
        int n = 10, x = 2;

        System.out.println(numOfWays(n, x));
    }
}
Python
def numOfWays(n, x):
    mod = 10**9 + 7
    dp = [0] * (n + 1)

    # One way to form sum 0: choose no numbers.
    dp[0] = 1

    num = 1

    while True:
        power = 1

        # Calculate num^x.
        for _ in range(x):
            power *= num

        # No larger number can contribute if num^x > n.
        if power > n:
            break

        # Traverse backwards so that num^x is used at most once.
        for total in range(n, power - 1, -1):
            dp[total] = (dp[total] + dp[total - power]) % mod

        num += 1

    return dp[n]


if __name__ == "__main__":
    # Input: n = 10, x = 2
    # Output: 1
    # Explanation: 10 = 1^2 + 3^2

    n = 10
    x = 2

    print(numOfWays(n, x))
C#
using System;

public class GFG
{
    const int MOD = 1000000007;

    static int numOfWays(int n, int x)
    {
        int[] dp = new int[n + 1];

        // One way to form sum 0: choose no numbers.
        dp[0] = 1;

        for (int num = 1; ; num++)
        {
            int power = 1;

            // Calculate num^x
            for (int j = 0; j < x; j++)
                power *= num;

            // No larger number can contribute if num^x > n
            if (power > n)
                break;

            // Traverse backwards so that num^x is used at most once.
            for (int sum = n; sum >= power; sum--)
            {
                dp[sum] =
                    (dp[sum] + dp[sum - power]) % MOD;
            }
        }

        return dp[n];
    }

    public static void Main()
    {
        int n = 10, x = 2;

        Console.WriteLine(numOfWays(n, x));
    }
}
JavaScript
function numOfWays(n, x) {
    const mod = 1000000007;
    const dp = new Array(n + 1).fill(0);

    // One way to form sum 0: choose no numbers.
    dp[0] = 1;

    let num = 1;

    while (true) {
        let power = 1;

        // Calculate num^x.
        for (let i = 0; i < x; i++)
            power *= num;

        // No larger number can contribute if num^x > n.
        if (power > n)
            break;

        // Traverse backwards so that num^x is used at most once.
        for (let total = n; total >= power; total--) {
            dp[total] = (dp[total] + dp[total - power]) % mod;
        }

        num++;
    }

    return dp[n];
}

function main() {
    // Input: n = 10, x = 2
    // Output: 1
    // Explanation: 10 = 1^2 + 3^2

    const n = 10;
    const x = 2;

    console.log(numOfWays(n, x));
}

main();

Output
1


Comment