LeetCode Entry
2787. Ways to Express an Integer as Sum of Powers
Ways to make n by sum of a^x+b^x+...
2787. Ways to Express an Integer as Sum of Powers medium blog post substack youtube
Join me on Telegram
https://t.me/leetcode_daily_unstoppable/1078
Problem TLDR
Ways to make n by sum of a^x+b^x+… #medium #dp
Intuition
Solved not optimally.
Consider all numbers: p = 1, 2, 3, ... a, b, c ... n and their x-powers: pow = a^x b^x c^x.
Do depth-first search, at each step make a decision:
- take the number:
v + a^x, p++ - or skip it:
v, p++If we arrive atv==nwe have a one good combination, return1. Cache the answer for inputsv, p.
For optimization, rewrite to iterate over the same values v, p, reversing the ranges.
Then do a space optimization, as we always look at p+1 previous row.
Approach
- I guess it is always good to start with simple choice instead of range iteration inside DFS
Complexity
-
Time complexity: \(O(n^2)\)
-
Space complexity: \(O(n)\)
Code
// 1092ms
fun numberOfWays(n: Int, x: Int): Int {
val m = 1000000007; var maxp = n; val pow = IntArray(n + 1) { 1 }
for (i in pow.indices) for (j in 1..x) {
pow[i] *= i; if (pow[i] > n) maxp = min(maxp, i)
}
val ways = Array(maxp + 2) { IntArray(n + 1) }
for (i in ways.indices) ways[i][0] = 1
for (x in 1..n) for (from in maxp downTo 1)
for (y in from..maxp) {
if (x - pow[y] < 0) break
ways[from][x] = (ways[from][x] + ways[y + 1][x - pow[y]])%m
}
return ways[1][n]
}
// 657ms
fun numberOfWays(n: Int, x: Int): Int {
val m = 1000000007; val dp = HashMap<Pair<Int, Int>, Int>()
fun dfs(v: Int, p: Int): Int = dp.getOrPut(v to p) {
if (v == 0) 1 else if (v < 0 || p > v || Math.pow(1.0*p, 1.0*x).toInt() > v) 0
else (dfs(v - Math.pow(1.0*p, 1.0*x).toInt(), p + 1) + dfs(v, p + 1)) % m
}
return dfs(n, 1)
}
// 15ms
fun numberOfWays(n: Int, x: Int): Int {
val m = 1000000007; val ways = IntArray(n + 1); ways[0] = 1
for (p in 1..n) {
var pow = 1; for (i in 1..x) pow *= p; if (pow > n) break
for (v in n downTo pow) ways[v] = (ways[v] + ways[v - pow]) % m
}
return ways[n]
}
// 0ms
pub fn number_of_ways(n: i32, x: i32) -> i32 {
let mut dp = [0;301]; let n = n as usize; dp[0] = 1;
for p in 1..=n {
let pow = p.pow(x as u32);
for v in (pow..=n).rev() { dp[v] = (dp[v] + dp[v - pow]) % 1000000007 }
} dp[n]
}
// 14ms
int numberOfWays(int n, int x) {
int d[301]={}; d[0] = 1;
for (int p = 1; p <= n && pow(p, x) <= n; ++p)
for (int v = n, pw = pow(p, x); v >= pw; --v)
d[v] = (d[v] + d[v-pw]) % 1000000007;
return d[n];
}
// 363ms
def numberOfWays(self, n: int, x: int) -> int:
d = [1] + [0] * n
for p in range(1, n + 1):
for v in range(n, p ** x - 1, -1):
d[v] = (d[v] + d[v - p ** x]) % 1000000007
return d[n]