From 25fced857b85e10d29168bc610456c20b5ee9142 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 20 Oct 2023 18:19:14 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.1155 No.1155.Number of Dice Rolls With Target Sum --- .../README.md | 156 +++++++++++++++- .../README_EN.md | 168 +++++++++++++++++- .../Solution.cpp | 33 ++-- .../Solution.go | 13 +- .../Solution.java | 30 ++-- .../Solution.py | 21 +-- .../Solution.rs | 22 +++ .../Solution.ts | 12 +- 8 files changed, 395 insertions(+), 60 deletions(-) create mode 100644 solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.rs diff --git a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/README.md b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/README.md index e5a645214ef1b..be5790ab43978 100644 --- a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/README.md +++ b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/README.md @@ -62,10 +62,12 @@ $$ 其中 $h$ 表示第 $i$ 个骰子的点数。 -最终的答案即为 $f[n][target]$。 +初始时 $f[0][0] = 1$,最终的答案即为 $f[n][target]$。 时间复杂度 $O(n \times k \times target)$,空间复杂度 $O(n \times target)$。 +我们注意到,状态 $f[i][j]$ 只和 $f[i-1][]$ 有关,因此我们可以使用滚动数组的方式,将空间复杂度优化到 $O(target)$。 + ### **Python3** @@ -85,6 +87,20 @@ class Solution: return f[n][target] ``` +```python +class Solution: + def numRollsToTarget(self, n: int, k: int, target: int) -> int: + f = [1] + [0] * target + mod = 10**9 + 7 + for i in range(1, n + 1): + g = [0] * (target + 1) + for j in range(1, min(i * k, target) + 1): + for h in range(1, min(j, k) + 1): + g[j] = (g[j] + f[j - h]) % mod + f = g + return f[target] +``` + ### **Java** @@ -107,6 +123,26 @@ class Solution { } ``` +```java +class Solution { + public int numRollsToTarget(int n, int k, int target) { + final int mod = (int) 1e9 + 7; + int[] f = new int[target + 1]; + f[0] = 1; + for (int i = 1; i <= n; ++i) { + int[] g = new int[target + 1]; + for (int j = 1; j <= Math.min(target, i * k); ++j) { + for (int h = 1; h <= Math.min(j, k); ++h) { + g[j] = (g[j] + f[j - h]) % mod; + } + } + f = g; + } + return f[target]; + } +} +``` + ### **C++** ```cpp @@ -129,6 +165,27 @@ public: }; ``` +```cpp +class Solution { +public: + int numRollsToTarget(int n, int k, int target) { + const int mod = 1e9 + 7; + vector f(target + 1); + f[0] = 1; + for (int i = 1; i <= n; ++i) { + vector g(target + 1); + for (int j = 1; j <= min(target, i * k); ++j) { + for (int h = 1; h <= min(j, k); ++h) { + g[j] = (g[j] + f[j - h]) % mod; + } + } + f = move(g); + } + return f[target]; + } +}; +``` + ### **Go** ```go @@ -157,13 +214,36 @@ func min(a, b int) int { } ``` +```go +func numRollsToTarget(n int, k int, target int) int { + const mod int = 1e9 + 7 + f := make([]int, target+1) + f[0] = 1 + for i := 1; i <= n; i++ { + g := make([]int, target+1) + for j := 1; j <= min(target, i*k); j++ { + for h := 1; h <= min(j, k); h++ { + g[j] = (g[j] + f[j-h]) % mod + } + } + f = g + } + return f[target] +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` + ### **TypeScript** ```ts function numRollsToTarget(n: number, k: number, target: number): number { - const f = Array(n + 1) - .fill(0) - .map(() => Array(target + 1).fill(0)); + const f = Array.from({ length: n + 1 }, () => Array(target + 1).fill(0)); f[0][0] = 1; const mod = 1e9 + 7; for (let i = 1; i <= n; ++i) { @@ -177,6 +257,74 @@ function numRollsToTarget(n: number, k: number, target: number): number { } ``` +```ts +function numRollsToTarget(n: number, k: number, target: number): number { + const f = Array(target + 1).fill(0); + f[0] = 1; + const mod = 1e9 + 7; + for (let i = 1; i <= n; ++i) { + const g = Array(target + 1).fill(0); + for (let j = 1; j <= Math.min(i * k, target); ++j) { + for (let h = 1; h <= Math.min(j, k); ++h) { + g[j] = (g[j] + f[j - h]) % mod; + } + } + f.splice(0, target + 1, ...g); + } + return f[target]; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn num_rolls_to_target(n: i32, k: i32, target: i32) -> i32 { + let _mod = 1_000_000_007; + let n = n as usize; + let k = k as usize; + let target = target as usize; + let mut f = vec![vec![0; target + 1]; n + 1]; + f[0][0] = 1; + + for i in 1..=n { + for j in 1..=target.min(i * k) { + for h in 1..=j.min(k) { + f[i][j] = (f[i][j] + f[i - 1][j - h]) % _mod; + } + } + } + + f[n][target] + } +} +``` + +```rust +impl Solution { + pub fn num_rolls_to_target(n: i32, k: i32, target: i32) -> i32 { + let _mod = 1_000_000_007; + let n = n as usize; + let k = k as usize; + let target = target as usize; + let mut f = vec![0; target + 1]; + f[0] = 1; + + for i in 1..=n { + let mut g = vec![0; target + 1]; + for j in 1..=target { + for h in 1..=j.min(k) { + g[j] = (g[j] + f[j - h]) % _mod; + } + } + f = g; + } + + f[target] + } +} +``` + ### **...** ``` diff --git a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/README_EN.md b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/README_EN.md index 1bd7db76df9f4..2b8c142a1c770 100644 --- a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/README_EN.md +++ b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/README_EN.md @@ -45,6 +45,22 @@ There are 6 ways to get a sum of 7: 1+6, 2+5, 3+4, 4+3, 5+2, 6+1. ## Solutions +**Solution 1: Dynamic Programming** + +We define $f[i][j]$ as the number of ways to get a sum of $j$ using $i$ dice. Then, we can obtain the following state transition equation: + +$$ +f[i][j] = \sum_{h=1}^{\min(j, k)} f[i-1][j-h] +$$ + +where $h$ represents the number of points on the $i$-th die. + +Initially, we have $f[0][0] = 1$, and the final answer is $f[n][target]$. + +The time complexity is $O(n \times k \times target)$, and the space complexity is $O(n \times target)$. + +We notice that the state $f[i][j]$ only depends on $f[i-1][]$, so we can use a rolling array to optimize the space complexity to $O(target)$. + ### **Python3** @@ -62,6 +78,20 @@ class Solution: return f[n][target] ``` +```python +class Solution: + def numRollsToTarget(self, n: int, k: int, target: int) -> int: + f = [1] + [0] * target + mod = 10**9 + 7 + for i in range(1, n + 1): + g = [0] * (target + 1) + for j in range(1, min(i * k, target) + 1): + for h in range(1, min(j, k) + 1): + g[j] = (g[j] + f[j - h]) % mod + f = g + return f[target] +``` + ### **Java** ```java @@ -82,6 +112,26 @@ class Solution { } ``` +```java +class Solution { + public int numRollsToTarget(int n, int k, int target) { + final int mod = (int) 1e9 + 7; + int[] f = new int[target + 1]; + f[0] = 1; + for (int i = 1; i <= n; ++i) { + int[] g = new int[target + 1]; + for (int j = 1; j <= Math.min(target, i * k); ++j) { + for (int h = 1; h <= Math.min(j, k); ++h) { + g[j] = (g[j] + f[j - h]) % mod; + } + } + f = g; + } + return f[target]; + } +} +``` + ### **C++** ```cpp @@ -104,6 +154,27 @@ public: }; ``` +```cpp +class Solution { +public: + int numRollsToTarget(int n, int k, int target) { + const int mod = 1e9 + 7; + vector f(target + 1); + f[0] = 1; + for (int i = 1; i <= n; ++i) { + vector g(target + 1); + for (int j = 1; j <= min(target, i * k); ++j) { + for (int h = 1; h <= min(j, k); ++h) { + g[j] = (g[j] + f[j - h]) % mod; + } + } + f = move(g); + } + return f[target]; + } +}; +``` + ### **Go** ```go @@ -132,13 +203,36 @@ func min(a, b int) int { } ``` +```go +func numRollsToTarget(n int, k int, target int) int { + const mod int = 1e9 + 7 + f := make([]int, target+1) + f[0] = 1 + for i := 1; i <= n; i++ { + g := make([]int, target+1) + for j := 1; j <= min(target, i*k); j++ { + for h := 1; h <= min(j, k); h++ { + g[j] = (g[j] + f[j-h]) % mod + } + } + f = g + } + return f[target] +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` + ### **TypeScript** ```ts function numRollsToTarget(n: number, k: number, target: number): number { - const f = Array(n + 1) - .fill(0) - .map(() => Array(target + 1).fill(0)); + const f = Array.from({ length: n + 1 }, () => Array(target + 1).fill(0)); f[0][0] = 1; const mod = 1e9 + 7; for (let i = 1; i <= n; ++i) { @@ -152,6 +246,74 @@ function numRollsToTarget(n: number, k: number, target: number): number { } ``` +```ts +function numRollsToTarget(n: number, k: number, target: number): number { + const f = Array(target + 1).fill(0); + f[0] = 1; + const mod = 1e9 + 7; + for (let i = 1; i <= n; ++i) { + const g = Array(target + 1).fill(0); + for (let j = 1; j <= Math.min(i * k, target); ++j) { + for (let h = 1; h <= Math.min(j, k); ++h) { + g[j] = (g[j] + f[j - h]) % mod; + } + } + f.splice(0, target + 1, ...g); + } + return f[target]; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn num_rolls_to_target(n: i32, k: i32, target: i32) -> i32 { + let _mod = 1_000_000_007; + let n = n as usize; + let k = k as usize; + let target = target as usize; + let mut f = vec![vec![0; target + 1]; n + 1]; + f[0][0] = 1; + + for i in 1..=n { + for j in 1..=target.min(i * k) { + for h in 1..=j.min(k) { + f[i][j] = (f[i][j] + f[i - 1][j - h]) % _mod; + } + } + } + + f[n][target] + } +} +``` + +```rust +impl Solution { + pub fn num_rolls_to_target(n: i32, k: i32, target: i32) -> i32 { + let _mod = 1_000_000_007; + let n = n as usize; + let k = k as usize; + let target = target as usize; + let mut f = vec![0; target + 1]; + f[0] = 1; + + for i in 1..=n { + let mut g = vec![0; target + 1]; + for j in 1..=target { + for h in 1..=j.min(k) { + g[j] = (g[j] + f[j - h]) % _mod; + } + } + f = g; + } + + f[target] + } +} +``` + ### **...** ``` diff --git a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.cpp b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.cpp index 1211e2fe0527a..4ef52dc6a9f0f 100644 --- a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.cpp +++ b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.cpp @@ -1,17 +1,18 @@ -class Solution { -public: - int numRollsToTarget(int n, int k, int target) { - const int mod = 1e9 + 7; - int f[n + 1][target + 1]; - memset(f, 0, sizeof f); - f[0][0] = 1; - for (int i = 1; i <= n; ++i) { - for (int j = 1; j <= min(target, i * k); ++j) { - for (int h = 1; h <= min(j, k); ++h) { - f[i][j] = (f[i][j] + f[i - 1][j - h]) % mod; - } - } - } - return f[n][target]; - } +class Solution { +public: + int numRollsToTarget(int n, int k, int target) { + const int mod = 1e9 + 7; + vector f(target + 1); + f[0] = 1; + for (int i = 1; i <= n; ++i) { + vector g(target + 1); + for (int j = 1; j <= min(target, i * k); ++j) { + for (int h = 1; h <= min(j, k); ++h) { + g[j] = (g[j] + f[j - h]) % mod; + } + } + f = move(g); + } + return f[target]; + } }; \ No newline at end of file diff --git a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.go b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.go index 4883d81a0d826..a4ec70475cb6a 100644 --- a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.go +++ b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.go @@ -1,18 +1,17 @@ func numRollsToTarget(n int, k int, target int) int { const mod int = 1e9 + 7 - f := make([][]int, n+1) - for i := range f { - f[i] = make([]int, target+1) - } - f[0][0] = 1 + f := make([]int, target+1) + f[0] = 1 for i := 1; i <= n; i++ { + g := make([]int, target+1) for j := 1; j <= min(target, i*k); j++ { for h := 1; h <= min(j, k); h++ { - f[i][j] = (f[i][j] + f[i-1][j-h]) % mod + g[j] = (g[j] + f[j-h]) % mod } } + f = g } - return f[n][target] + return f[target] } func min(a, b int) int { diff --git a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.java b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.java index 6abe7d99e599a..9b1cb488f82f7 100644 --- a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.java +++ b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.java @@ -1,15 +1,17 @@ -class Solution { - public int numRollsToTarget(int n, int k, int target) { - final int mod = (int) 1e9 + 7; - int[][] f = new int[n + 1][target + 1]; - f[0][0] = 1; - for (int i = 1; i <= n; ++i) { - for (int j = 1; j <= Math.min(target, i * k); ++j) { - for (int h = 1; h <= Math.min(j, k); ++h) { - f[i][j] = (f[i][j] + f[i - 1][j - h]) % mod; - } - } - } - return f[n][target]; - } +class Solution { + public int numRollsToTarget(int n, int k, int target) { + final int mod = (int) 1e9 + 7; + int[] f = new int[target + 1]; + f[0] = 1; + for (int i = 1; i <= n; ++i) { + int[] g = new int[target + 1]; + for (int j = 1; j <= Math.min(target, i * k); ++j) { + for (int h = 1; h <= Math.min(j, k); ++h) { + g[j] = (g[j] + f[j - h]) % mod; + } + } + f = g; + } + return f[target]; + } } \ No newline at end of file diff --git a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.py b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.py index d6c1708c98482..55b735815d696 100644 --- a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.py +++ b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.py @@ -1,10 +1,11 @@ -class Solution: - def numRollsToTarget(self, n: int, k: int, target: int) -> int: - f = [[0] * (target + 1) for _ in range(n + 1)] - f[0][0] = 1 - mod = 10**9 + 7 - for i in range(1, n + 1): - for j in range(1, min(i * k, target) + 1): - for h in range(1, min(j, k) + 1): - f[i][j] = (f[i][j] + f[i - 1][j - h]) % mod - return f[n][target] +class Solution: + def numRollsToTarget(self, n: int, k: int, target: int) -> int: + f = [1] + [0] * target + mod = 10**9 + 7 + for i in range(1, n + 1): + g = [0] * (target + 1) + for j in range(1, min(i * k, target) + 1): + for h in range(1, min(j, k) + 1): + g[j] = (g[j] + f[j - h]) % mod + f = g + return f[target] diff --git a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.rs b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.rs new file mode 100644 index 0000000000000..387f6ed000056 --- /dev/null +++ b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.rs @@ -0,0 +1,22 @@ +impl Solution { + pub fn num_rolls_to_target(n: i32, k: i32, target: i32) -> i32 { + let _mod = 1_000_000_007; + let n = n as usize; + let k = k as usize; + let target = target as usize; + let mut f = vec![0; target + 1]; + f[0] = 1; + + for i in 1..=n { + let mut g = vec![0; target + 1]; + for j in 1..=target { + for h in 1..=j.min(k) { + g[j] = (g[j] + f[j - h]) % _mod; + } + } + f = g; + } + + f[target] + } +} \ No newline at end of file diff --git a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.ts b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.ts index 4bc24dc354162..705b0c1cb1b1a 100644 --- a/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.ts +++ b/solution/1100-1199/1155.Number of Dice Rolls With Target Sum/Solution.ts @@ -1,15 +1,15 @@ function numRollsToTarget(n: number, k: number, target: number): number { - const f = Array(n + 1) - .fill(0) - .map(() => Array(target + 1).fill(0)); - f[0][0] = 1; + const f = Array(target + 1).fill(0); + f[0] = 1; const mod = 1e9 + 7; for (let i = 1; i <= n; ++i) { + const g = Array(target + 1).fill(0); for (let j = 1; j <= Math.min(i * k, target); ++j) { for (let h = 1; h <= Math.min(j, k); ++h) { - f[i][j] = (f[i][j] + f[i - 1][j - h]) % mod; + g[j] = (g[j] + f[j - h]) % mod; } } + f.splice(0, target + 1, ...g); } - return f[n][target]; + return f[target]; }