Skip to content

Commit d469b75

Browse files
authored
feat: add solutions to lc problem: No.2787 (doocs#4623)
No.2787.Ways to Express an Integer as Sum of Powers
1 parent 1191ada commit d469b75

File tree

4 files changed

+106
-11
lines changed

4 files changed

+106
-11
lines changed

solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README.md

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,24 @@ tags:
6060

6161
<!-- solution:start -->
6262

63-
### 方法一
63+
### 方法一:动态规划
64+
65+
我们定义 $f[i][j]$ 表示在前 $i$ 个正整数中选取一些数的 $x$ 次幂之和等于 $j$ 的方案数,初始时 $f[0][0] = 1$,其余均为 $0$。答案为 $f[n][n]$。
66+
67+
对于每个正整数 $i$,我们可以选择不选它或者选它:
68+
69+
- 不选它:此时方案数为 $f[i-1][j]$;
70+
- 选它:此时方案数为 $f[i-1][j-i^x]$(前提是 $j \geq i^x$)。
71+
72+
因此状态转移方程为:
73+
74+
$$
75+
f[i][j] = f[i-1][j] + (j \geq i^x ? f[i-1][j-i^x] : 0)
76+
$$
77+
78+
注意到答案可能非常大,我们需要对 $10^9 + 7$ 取余。
79+
80+
时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是题目中给定的整数。
6481

6582
<!-- tabs:start -->
6683

@@ -155,9 +172,7 @@ func numberOfWays(n int, x int) int {
155172
```ts
156173
function numberOfWays(n: number, x: number): number {
157174
const mod = 10 ** 9 + 7;
158-
const f: number[][] = Array(n + 1)
159-
.fill(0)
160-
.map(() => Array(n + 1).fill(0));
175+
const f = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
161176
f[0][0] = 1;
162177
for (let i = 1; i <= n; ++i) {
163178
const k = Math.pow(i, x);
@@ -172,6 +187,30 @@ function numberOfWays(n: number, x: number): number {
172187
}
173188
```
174189

190+
#### Rust
191+
192+
```rust
193+
impl Solution {
194+
pub fn number_of_ways(n: i32, x: i32) -> i32 {
195+
const MOD: i64 = 1_000_000_007;
196+
let n = n as usize;
197+
let x = x as u32;
198+
let mut f = vec![vec![0; n + 1]; n + 1];
199+
f[0][0] = 1;
200+
for i in 1..=n {
201+
let k = (i as i64).pow(x);
202+
for j in 0..=n {
203+
f[i][j] = f[i - 1][j];
204+
if j >= k as usize {
205+
f[i][j] = (f[i][j] + f[i - 1][j - k as usize]) % MOD;
206+
}
207+
}
208+
}
209+
f[n][n] as i32
210+
}
211+
}
212+
```
213+
175214
<!-- tabs:end -->
176215

177216
<!-- solution:end -->

solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/README_EN.md

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,24 @@ It can be shown that it is the only way to express 10 as the sum of the 2<sup>nd
6060

6161
<!-- solution:start -->
6262

63-
### Solution 1
63+
### Solution 1: Dynamic Programming
64+
65+
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]$.
66+
67+
For each positive integer $i$, we can choose to either include it or not:
68+
69+
- Not include it: the number of ways is $f[i-1][j]$;
70+
- Include it: the number of ways is $f[i-1][j-i^x]$ (provided that $j \geq i^x$).
71+
72+
Therefore, the state transition equation is:
73+
74+
$$
75+
f[i][j] = f[i-1][j] + (j \geq i^x ? f[i-1][j-i^x] : 0)
76+
$$
77+
78+
Note that the answer can be very large, so we need to take modulo $10^9 + 7$.
79+
80+
The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$, where $n$ is the given integer in the
6481

6582
<!-- tabs:start -->
6683

@@ -155,9 +172,7 @@ func numberOfWays(n int, x int) int {
155172
```ts
156173
function numberOfWays(n: number, x: number): number {
157174
const mod = 10 ** 9 + 7;
158-
const f: number[][] = Array(n + 1)
159-
.fill(0)
160-
.map(() => Array(n + 1).fill(0));
175+
const f = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
161176
f[0][0] = 1;
162177
for (let i = 1; i <= n; ++i) {
163178
const k = Math.pow(i, x);
@@ -172,6 +187,30 @@ function numberOfWays(n: number, x: number): number {
172187
}
173188
```
174189

190+
#### Rust
191+
192+
```rust
193+
impl Solution {
194+
pub fn number_of_ways(n: i32, x: i32) -> i32 {
195+
const MOD: i64 = 1_000_000_007;
196+
let n = n as usize;
197+
let x = x as u32;
198+
let mut f = vec![vec![0; n + 1]; n + 1];
199+
f[0][0] = 1;
200+
for i in 1..=n {
201+
let k = (i as i64).pow(x);
202+
for j in 0..=n {
203+
f[i][j] = f[i - 1][j];
204+
if j >= k as usize {
205+
f[i][j] = (f[i][j] + f[i - 1][j - k as usize]) % MOD;
206+
}
207+
}
208+
}
209+
f[n][n] as i32
210+
}
211+
}
212+
```
213+
175214
<!-- tabs:end -->
176215

177216
<!-- solution:end -->
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
impl Solution {
2+
pub fn number_of_ways(n: i32, x: i32) -> i32 {
3+
const MOD: i64 = 1_000_000_007;
4+
let n = n as usize;
5+
let x = x as u32;
6+
let mut f = vec![vec![0; n + 1]; n + 1];
7+
f[0][0] = 1;
8+
for i in 1..=n {
9+
let k = (i as i64).pow(x);
10+
for j in 0..=n {
11+
f[i][j] = f[i - 1][j];
12+
if j >= k as usize {
13+
f[i][j] = (f[i][j] + f[i - 1][j - k as usize]) % MOD;
14+
}
15+
}
16+
}
17+
f[n][n] as i32
18+
}
19+
}

solution/2700-2799/2787.Ways to Express an Integer as Sum of Powers/Solution.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
function numberOfWays(n: number, x: number): number {
22
const mod = 10 ** 9 + 7;
3-
const f: number[][] = Array(n + 1)
4-
.fill(0)
5-
.map(() => Array(n + 1).fill(0));
3+
const f = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
64
f[0][0] = 1;
75
for (let i = 1; i <= n; ++i) {
86
const k = Math.pow(i, x);

0 commit comments

Comments
 (0)