From d469b75e4e2ca82e586128a0d4cd630c2a19d568 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 6 Aug 2025 07:31:38 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.2787 (#4623) No.2787.Ways to Express an Integer as Sum of Powers --- .../README.md | 47 +++++++++++++++++-- .../README_EN.md | 47 +++++++++++++++++-- .../Solution.rs | 19 ++++++++ .../Solution.ts | 4 +- 4 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.rs diff --git a/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README.md b/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README.md index 14351bbdf47ba..11765ee990683 100644 --- a/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README.md +++ b/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README.md @@ -60,7 +60,24 @@ tags: -### 方法一 +### 方法一:动态规划 + +我们定义 $f[i][j]$ 表示在前 $i$ 个正整数中选取一些数的 $x$ 次幂之和等于 $j$ 的方案数,初始时 $f[0][0] = 1$,其余均为 $0$。答案为 $f[n][n]$。 + +对于每个正整数 $i$,我们可以选择不选它或者选它: + +- 不选它:此时方案数为 $f[i-1][j]$; +- 选它:此时方案数为 $f[i-1][j-i^x]$(前提是 $j \geq i^x$)。 + +因此状态转移方程为: + +$$ +f[i][j] = f[i-1][j] + (j \geq i^x ? f[i-1][j-i^x] : 0) +$$ + +注意到答案可能非常大,我们需要对 $10^9 + 7$ 取余。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是题目中给定的整数。 @@ -155,9 +172,7 @@ func numberOfWays(n int, x int) int { ```ts function numberOfWays(n: number, x: number): number { const mod = 10 ** 9 + 7; - const f: number[][] = Array(n + 1) - .fill(0) - .map(() => Array(n + 1).fill(0)); + const f = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0)); f[0][0] = 1; for (let i = 1; i <= n; ++i) { const k = Math.pow(i, x); @@ -172,6 +187,30 @@ function numberOfWays(n: number, x: number): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn number_of_ways(n: i32, x: i32) -> i32 { + const MOD: i64 = 1_000_000_007; + let n = n as usize; + let x = x as u32; + let mut f = vec![vec![0; n + 1]; n + 1]; + f[0][0] = 1; + for i in 1..=n { + let k = (i as i64).pow(x); + for j in 0..=n { + f[i][j] = f[i - 1][j]; + if j >= k as usize { + f[i][j] = (f[i][j] + f[i - 1][j - k as usize]) % MOD; + } + } + } + f[n][n] as i32 + } +} +``` + diff --git a/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README_EN.md b/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README_EN.md index 7b305c05503a0..f1a00799e35cb 100644 --- a/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README_EN.md +++ b/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README_EN.md @@ -60,7 +60,24 @@ It can be shown that it is the only way to express 10 as the sum of the 2nd -### Solution 1 +### Solution 1: Dynamic Programming + +We define $f[i][j]$ as the number of ways to select some numbers from the first $i$ positive integers such that the sum of their $x$-th powers equals $j$. Initially, $f[0][0] = 1$, and all others are $0$. The answer is $f[n][n]$. + +For each positive integer $i$, we can choose to either include it or not: + +- Not include it: the number of ways is $f[i-1][j]$; +- Include it: the number of ways is $f[i-1][j-i^x]$ (provided that $j \geq i^x$). + +Therefore, the state transition equation is: + +$$ +f[i][j] = f[i-1][j] + (j \geq i^x ? f[i-1][j-i^x] : 0) +$$ + +Note that the answer can be very large, so we need to take modulo $10^9 + 7$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$, where $n$ is the given integer in the @@ -155,9 +172,7 @@ func numberOfWays(n int, x int) int { ```ts function numberOfWays(n: number, x: number): number { const mod = 10 ** 9 + 7; - const f: number[][] = Array(n + 1) - .fill(0) - .map(() => Array(n + 1).fill(0)); + const f = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0)); f[0][0] = 1; for (let i = 1; i <= n; ++i) { const k = Math.pow(i, x); @@ -172,6 +187,30 @@ function numberOfWays(n: number, x: number): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn number_of_ways(n: i32, x: i32) -> i32 { + const MOD: i64 = 1_000_000_007; + let n = n as usize; + let x = x as u32; + let mut f = vec![vec![0; n + 1]; n + 1]; + f[0][0] = 1; + for i in 1..=n { + let k = (i as i64).pow(x); + for j in 0..=n { + f[i][j] = f[i - 1][j]; + if j >= k as usize { + f[i][j] = (f[i][j] + f[i - 1][j - k as usize]) % MOD; + } + } + } + f[n][n] as i32 + } +} +``` + diff --git a/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.rs b/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.rs new file mode 100644 index 0000000000000..018e389b27799 --- /dev/null +++ b/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.rs @@ -0,0 +1,19 @@ +impl Solution { + pub fn number_of_ways(n: i32, x: i32) -> i32 { + const MOD: i64 = 1_000_000_007; + let n = n as usize; + let x = x as u32; + let mut f = vec![vec![0; n + 1]; n + 1]; + f[0][0] = 1; + for i in 1..=n { + let k = (i as i64).pow(x); + for j in 0..=n { + f[i][j] = f[i - 1][j]; + if j >= k as usize { + f[i][j] = (f[i][j] + f[i - 1][j - k as usize]) % MOD; + } + } + } + f[n][n] as i32 + } +} diff --git a/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.ts b/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.ts index 9c7c4bc3290a5..e61b2ac422c08 100644 --- a/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.ts +++ b/solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.ts @@ -1,8 +1,6 @@ function numberOfWays(n: number, x: number): number { const mod = 10 ** 9 + 7; - const f: number[][] = Array(n + 1) - .fill(0) - .map(() => Array(n + 1).fill(0)); + const f = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0)); f[0][0] = 1; for (let i = 1; i <= n; ++i) { const k = Math.pow(i, x);