From 9113d93addd96b5f676a293c0a9fc9d7748eb3b1 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 21 Jan 2025 09:42:07 +0800 Subject: [PATCH 1/2] feat: add solutions to lc problem: No.2218 No.2218.Maximum Value of K Coins From Piles --- .../README.md | 237 +++++++++++++----- .../README_EN.md | 237 +++++++++++++----- .../Solution.cpp | 27 +- .../Solution.go | 34 +-- .../Solution.java | 29 +-- .../Solution.py | 15 +- .../Solution.ts | 17 ++ .../Solution2.cpp | 18 ++ .../Solution2.go | 15 ++ .../Solution2.java | 17 ++ .../Solution2.py | 15 +- .../Solution2.ts | 15 ++ 12 files changed, 493 insertions(+), 183 deletions(-) create mode 100644 solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.ts create mode 100644 solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.cpp create mode 100644 solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.go create mode 100644 solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.java create mode 100644 solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.ts diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README.md b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README.md index 99afcc122fd0f..f929b08451b73 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README.md +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README.md @@ -66,15 +66,21 @@ tags: -### 方法一:动态规划 +### 方法一:动态规划(分组背包) -对每个栈求前缀和 $s$,$s_i$ 视为一个体积为 $i$ 且价值为 $s_i$ 的物品。 +我们定义 $f[i][j]$ 表示从前 $i$ 组中取出 $j$ 个硬币的最大面值和,那么答案为 $f[n][k]$,其中 $n$ 为栈的数量。 -问题转化为求从 $n$ 个物品组中取物品体积为 $k$,且每组最多取一个物品时的最大价值和。 +对于第 $i$ 组,我们可以选择取前 $0$, $1$, $2$, $\cdots$, $k$ 个硬币。我们可以通过前缀和数组 $s$ 来快速计算出取前 $h$ 个硬币的面值和。 -定义 $dp[i][j]$ 表示从前 $i$ 个组中取体积之和为 $j$ 的物品时的最大价值和。 +状态转移方程为: -枚举第 $i$ 组所有物品,设当前物品体积为 $w$,价值为 $v$,则有 $f[i][j]=max(f[i][j],f[i-1][j-w]+v)$。 +$$ +f[i][j] = \max(f[i][j], f[i - 1][j - h] + s[h]) +$$ + +其中 $0 \leq h \leq j$,而 $s[h]$ 表示第 $i$ 组中取前 $h$ 个硬币的面值和。 + +时间复杂度 $O(k \times L)$,空间复杂度 $O(n \times k)$。其中 $L$ 为所有硬币的数量,而 $n$ 为栈的数量。 @@ -83,15 +89,16 @@ tags: ```python class Solution: def maxValueOfCoins(self, piles: List[List[int]], k: int) -> int: - presum = [list(accumulate(p, initial=0)) for p in piles] n = len(piles) - dp = [[0] * (k + 1) for _ in range(n + 1)] - for i, s in enumerate(presum, 1): + f = [[0] * (k + 1) for _ in range(n + 1)] + for i, nums in enumerate(piles, 1): + s = list(accumulate(nums, initial=0)) for j in range(k + 1): - for idx, v in enumerate(s): - if j >= idx: - dp[i][j] = max(dp[i][j], dp[i - 1][j - idx] + v) - return dp[-1][-1] + for h, w in enumerate(s): + if j < h: + break + f[i][j] = max(f[i][j], f[i - 1][j - h] + w) + return f[n][k] ``` #### Java @@ -100,26 +107,21 @@ class Solution: class Solution { public int maxValueOfCoins(List> piles, int k) { int n = piles.size(); - List presum = new ArrayList<>(); - for (List p : piles) { - int m = p.size(); - int[] s = new int[m + 1]; - for (int i = 0; i < m; ++i) { - s[i + 1] = s[i] + p.get(i); + int[][] f = new int[n + 1][k + 1]; + for (int i = 1; i <= n; i++) { + List nums = piles.get(i - 1); + int[] s = new int[nums.size() + 1]; + s[0] = 0; + for (int j = 1; j <= nums.size(); j++) { + s[j] = s[j - 1] + nums.get(j - 1); } - presum.add(s); - } - int[] dp = new int[k + 1]; - for (int[] s : presum) { - for (int j = k; j >= 0; --j) { - for (int idx = 0; idx < s.length; ++idx) { - if (j >= idx) { - dp[j] = Math.max(dp[j], dp[j - idx] + s[idx]); - } + for (int j = 0; j <= k; j++) { + for (int h = 0; h < s.length && h <= j; h++) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - h] + s[h]); } } } - return dp[k]; + return f[n][k]; } } ``` @@ -130,22 +132,21 @@ class Solution { class Solution { public: int maxValueOfCoins(vector>& piles, int k) { - vector> presum; - for (auto& p : piles) { - int m = p.size(); - vector s(m + 1); - for (int i = 0; i < m; ++i) s[i + 1] = s[i] + p[i]; - presum.push_back(s); - } - vector dp(k + 1); - for (auto& s : presum) { - for (int j = k; ~j; --j) { - for (int idx = 0; idx < s.size(); ++idx) { - if (j >= idx) dp[j] = max(dp[j], dp[j - idx] + s[idx]); + int n = piles.size(); + vector> f(n + 1, vector(k + 1)); + for (int i = 1; i <= n; i++) { + vector nums = piles[i - 1]; + vector s(nums.size() + 1); + for (int j = 1; j <= nums.size(); j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (int j = 0; j <= k; j++) { + for (int h = 0; h < s.size() && h <= j; h++) { + f[i][j] = max(f[i][j], f[i - 1][j - h] + s[h]); } } } - return dp[k]; + return f[n][k]; } }; ``` @@ -154,26 +155,50 @@ public: ```go func maxValueOfCoins(piles [][]int, k int) int { - var presum [][]int - for _, p := range piles { - m := len(p) - s := make([]int, m+1) - for i, v := range p { - s[i+1] = s[i] + v - } - presum = append(presum, s) + n := len(piles) + f := make([][]int, n+1) + for i := range f { + f[i] = make([]int, k+1) } - dp := make([]int, k+1) - for _, s := range presum { - for j := k; j >= 0; j-- { - for idx, v := range s { - if j >= idx { - dp[j] = max(dp[j], dp[j-idx]+v) + for i := 1; i <= n; i++ { + nums := piles[i-1] + s := make([]int, len(nums)+1) + for j := 1; j <= len(nums); j++ { + s[j] = s[j-1] + nums[j-1] + } + + for j := 0; j <= k; j++ { + for h, w := range s { + if j < h { + break } + f[i][j] = max(f[i][j], f[i-1][j-h]+w) } } } - return dp[k] + return f[n][k] +} +``` + +#### TypeScript + +```ts +function maxValueOfCoins(piles: number[][], k: number): number { + const n = piles.length; + const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0)); + for (let i = 1; i <= n; i++) { + const nums = piles[i - 1]; + const s = Array(nums.length + 1).fill(0); + for (let j = 1; j <= nums.length; j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (let j = 0; j <= k; j++) { + for (let h = 0; h < s.length && h <= j; h++) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - h] + s[h]); + } + } + } + return f[n][k]; } ``` @@ -192,14 +217,100 @@ func maxValueOfCoins(piles [][]int, k int) int { ```python class Solution: def maxValueOfCoins(self, piles: List[List[int]], k: int) -> int: - presum = [list(accumulate(p, initial=0)) for p in piles] - dp = [0] * (k + 1) - for s in presum: + f = [0] * (k + 1) + for nums in piles: + s = list(accumulate(nums, initial=0)) for j in range(k, -1, -1): - for idx, v in enumerate(s): - if j >= idx: - dp[j] = max(dp[j], dp[j - idx] + v) - return dp[-1] + for h, w in enumerate(s): + if j < h: + break + f[j] = max(f[j], f[j - h] + w) + return f[k] +``` + +#### Java + +```java +class Solution { + public int maxValueOfCoins(List> piles, int k) { + int[] f = new int[k + 1]; + for (var nums : piles) { + int[] s = new int[nums.size() + 1]; + for (int j = 1; j <= nums.size(); ++j) { + s[j] = s[j - 1] + nums.get(j - 1); + } + for (int j = k; j >= 0; --j) { + for (int h = 0; h < s.length && h <= j; ++h) { + f[j] = Math.max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int maxValueOfCoins(vector>& piles, int k) { + vector f(k + 1); + for (auto& nums : piles) { + vector s(nums.size() + 1); + for (int j = 1; j <= nums.size(); ++j) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (int j = k; j >= 0; --j) { + for (int h = 0; h < s.size() && h <= j; ++h) { + f[j] = max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; + } +}; +``` + +#### Go + +```go +func maxValueOfCoins(piles [][]int, k int) int { + f := make([]int, k+1) + for _, nums := range piles { + s := make([]int, len(nums)+1) + for j := 1; j <= len(nums); j++ { + s[j] = s[j-1] + nums[j-1] + } + for j := k; j >= 0; j-- { + for h := 0; h < len(s) && h <= j; h++ { + f[j] = max(f[j], f[j-h]+s[h]) + } + } + } + return f[k] +} +``` + +#### TypeScript + +```ts +function maxValueOfCoins(piles: number[][], k: number): number { + const f: number[] = Array(k + 1).fill(0); + for (const nums of piles) { + const s: number[] = Array(nums.length + 1).fill(0); + for (let j = 1; j <= nums.length; j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (let j = k; j >= 0; j--) { + for (let h = 0; h < s.length && h <= j; h++) { + f[j] = Math.max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; +} ``` diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README_EN.md b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README_EN.md index 9cacb442c8d8c..5d72cb2cea20c 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README_EN.md +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README_EN.md @@ -62,7 +62,21 @@ The maximum total we can obtain is 101. -### Solution 1 +### Solution 1: Dynamic Programming (Grouped Knapsack) + +We define $f[i][j]$ as the maximum value sum of taking $j$ coins from the first $i$ piles. The answer is $f[n][k]$, where $n$ is the number of piles. + +For the $i$-th pile, we can choose to take the first $0$, $1$, $2$, $\cdots$, $k$ coins. We can use a prefix sum array $s$ to quickly calculate the value sum of taking the first $h$ coins. + +The state transition equation is: + +$$ +f[i][j] = \max(f[i][j], f[i - 1][j - h] + s[h]) +$$ + +where $0 \leq h \leq j$, and $s[h]$ represents the value sum of taking the first $h$ coins from the $i$-th pile. + +The time complexity is $O(k \times L)$, and the space complexity is $O(n \times k)$. Here, $L$ is the total number of coins, and $n$ is the number of piles. @@ -71,15 +85,16 @@ The maximum total we can obtain is 101. ```python class Solution: def maxValueOfCoins(self, piles: List[List[int]], k: int) -> int: - presum = [list(accumulate(p, initial=0)) for p in piles] n = len(piles) - dp = [[0] * (k + 1) for _ in range(n + 1)] - for i, s in enumerate(presum, 1): + f = [[0] * (k + 1) for _ in range(n + 1)] + for i, nums in enumerate(piles, 1): + s = list(accumulate(nums, initial=0)) for j in range(k + 1): - for idx, v in enumerate(s): - if j >= idx: - dp[i][j] = max(dp[i][j], dp[i - 1][j - idx] + v) - return dp[-1][-1] + for h, w in enumerate(s): + if j < h: + break + f[i][j] = max(f[i][j], f[i - 1][j - h] + w) + return f[n][k] ``` #### Java @@ -88,26 +103,21 @@ class Solution: class Solution { public int maxValueOfCoins(List> piles, int k) { int n = piles.size(); - List presum = new ArrayList<>(); - for (List p : piles) { - int m = p.size(); - int[] s = new int[m + 1]; - for (int i = 0; i < m; ++i) { - s[i + 1] = s[i] + p.get(i); + int[][] f = new int[n + 1][k + 1]; + for (int i = 1; i <= n; i++) { + List nums = piles.get(i - 1); + int[] s = new int[nums.size() + 1]; + s[0] = 0; + for (int j = 1; j <= nums.size(); j++) { + s[j] = s[j - 1] + nums.get(j - 1); } - presum.add(s); - } - int[] dp = new int[k + 1]; - for (int[] s : presum) { - for (int j = k; j >= 0; --j) { - for (int idx = 0; idx < s.length; ++idx) { - if (j >= idx) { - dp[j] = Math.max(dp[j], dp[j - idx] + s[idx]); - } + for (int j = 0; j <= k; j++) { + for (int h = 0; h < s.length && h <= j; h++) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - h] + s[h]); } } } - return dp[k]; + return f[n][k]; } } ``` @@ -118,22 +128,21 @@ class Solution { class Solution { public: int maxValueOfCoins(vector>& piles, int k) { - vector> presum; - for (auto& p : piles) { - int m = p.size(); - vector s(m + 1); - for (int i = 0; i < m; ++i) s[i + 1] = s[i] + p[i]; - presum.push_back(s); - } - vector dp(k + 1); - for (auto& s : presum) { - for (int j = k; ~j; --j) { - for (int idx = 0; idx < s.size(); ++idx) { - if (j >= idx) dp[j] = max(dp[j], dp[j - idx] + s[idx]); + int n = piles.size(); + vector> f(n + 1, vector(k + 1)); + for (int i = 1; i <= n; i++) { + vector nums = piles[i - 1]; + vector s(nums.size() + 1); + for (int j = 1; j <= nums.size(); j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (int j = 0; j <= k; j++) { + for (int h = 0; h < s.size() && h <= j; h++) { + f[i][j] = max(f[i][j], f[i - 1][j - h] + s[h]); } } } - return dp[k]; + return f[n][k]; } }; ``` @@ -142,26 +151,50 @@ public: ```go func maxValueOfCoins(piles [][]int, k int) int { - var presum [][]int - for _, p := range piles { - m := len(p) - s := make([]int, m+1) - for i, v := range p { - s[i+1] = s[i] + v - } - presum = append(presum, s) + n := len(piles) + f := make([][]int, n+1) + for i := range f { + f[i] = make([]int, k+1) } - dp := make([]int, k+1) - for _, s := range presum { - for j := k; j >= 0; j-- { - for idx, v := range s { - if j >= idx { - dp[j] = max(dp[j], dp[j-idx]+v) + for i := 1; i <= n; i++ { + nums := piles[i-1] + s := make([]int, len(nums)+1) + for j := 1; j <= len(nums); j++ { + s[j] = s[j-1] + nums[j-1] + } + + for j := 0; j <= k; j++ { + for h, w := range s { + if j < h { + break } + f[i][j] = max(f[i][j], f[i-1][j-h]+w) } } } - return dp[k] + return f[n][k] +} +``` + +#### TypeScript + +```ts +function maxValueOfCoins(piles: number[][], k: number): number { + const n = piles.length; + const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0)); + for (let i = 1; i <= n; i++) { + const nums = piles[i - 1]; + const s = Array(nums.length + 1).fill(0); + for (let j = 1; j <= nums.length; j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (let j = 0; j <= k; j++) { + for (let h = 0; h < s.length && h <= j; h++) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - h] + s[h]); + } + } + } + return f[n][k]; } ``` @@ -180,14 +213,100 @@ func maxValueOfCoins(piles [][]int, k int) int { ```python class Solution: def maxValueOfCoins(self, piles: List[List[int]], k: int) -> int: - presum = [list(accumulate(p, initial=0)) for p in piles] - dp = [0] * (k + 1) - for s in presum: + f = [0] * (k + 1) + for nums in piles: + s = list(accumulate(nums, initial=0)) for j in range(k, -1, -1): - for idx, v in enumerate(s): - if j >= idx: - dp[j] = max(dp[j], dp[j - idx] + v) - return dp[-1] + for h, w in enumerate(s): + if j < h: + break + f[j] = max(f[j], f[j - h] + w) + return f[k] +``` + +#### Java + +```java +class Solution { + public int maxValueOfCoins(List> piles, int k) { + int[] f = new int[k + 1]; + for (var nums : piles) { + int[] s = new int[nums.size() + 1]; + for (int j = 1; j <= nums.size(); ++j) { + s[j] = s[j - 1] + nums.get(j - 1); + } + for (int j = k; j >= 0; --j) { + for (int h = 0; h < s.length && h <= j; ++h) { + f[j] = Math.max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int maxValueOfCoins(vector>& piles, int k) { + vector f(k + 1); + for (auto& nums : piles) { + vector s(nums.size() + 1); + for (int j = 1; j <= nums.size(); ++j) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (int j = k; j >= 0; --j) { + for (int h = 0; h < s.size() && h <= j; ++h) { + f[j] = max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; + } +}; +``` + +#### Go + +```go +func maxValueOfCoins(piles [][]int, k int) int { + f := make([]int, k+1) + for _, nums := range piles { + s := make([]int, len(nums)+1) + for j := 1; j <= len(nums); j++ { + s[j] = s[j-1] + nums[j-1] + } + for j := k; j >= 0; j-- { + for h := 0; h < len(s) && h <= j; h++ { + f[j] = max(f[j], f[j-h]+s[h]) + } + } + } + return f[k] +} +``` + +#### TypeScript + +```ts +function maxValueOfCoins(piles: number[][], k: number): number { + const f: number[] = Array(k + 1).fill(0); + for (const nums of piles) { + const s: number[] = Array(nums.length + 1).fill(0); + for (let j = 1; j <= nums.length; j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (let j = k; j >= 0; j--) { + for (let h = 0; h < s.length && h <= j; h++) { + f[j] = Math.max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; +} ``` diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.cpp b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.cpp index 8f358e8405fa6..d3a21dcf4382c 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.cpp +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.cpp @@ -1,21 +1,20 @@ class Solution { public: int maxValueOfCoins(vector>& piles, int k) { - vector> presum; - for (auto& p : piles) { - int m = p.size(); - vector s(m + 1); - for (int i = 0; i < m; ++i) s[i + 1] = s[i] + p[i]; - presum.push_back(s); - } - vector dp(k + 1); - for (auto& s : presum) { - for (int j = k; ~j; --j) { - for (int idx = 0; idx < s.size(); ++idx) { - if (j >= idx) dp[j] = max(dp[j], dp[j - idx] + s[idx]); + int n = piles.size(); + vector> f(n + 1, vector(k + 1)); + for (int i = 1; i <= n; i++) { + vector nums = piles[i - 1]; + vector s(nums.size() + 1); + for (int j = 1; j <= nums.size(); j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (int j = 0; j <= k; j++) { + for (int h = 0; h < s.size() && h <= j; h++) { + f[i][j] = max(f[i][j], f[i - 1][j - h] + s[h]); } } } - return dp[k]; + return f[n][k]; } -}; \ No newline at end of file +}; diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.go b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.go index 74d3dd86f14f3..a0cb4ebba4062 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.go +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.go @@ -1,22 +1,24 @@ func maxValueOfCoins(piles [][]int, k int) int { - var presum [][]int - for _, p := range piles { - m := len(p) - s := make([]int, m+1) - for i, v := range p { - s[i+1] = s[i] + v - } - presum = append(presum, s) + n := len(piles) + f := make([][]int, n+1) + for i := range f { + f[i] = make([]int, k+1) } - dp := make([]int, k+1) - for _, s := range presum { - for j := k; j >= 0; j-- { - for idx, v := range s { - if j >= idx { - dp[j] = max(dp[j], dp[j-idx]+v) + for i := 1; i <= n; i++ { + nums := piles[i-1] + s := make([]int, len(nums)+1) + for j := 1; j <= len(nums); j++ { + s[j] = s[j-1] + nums[j-1] + } + + for j := 0; j <= k; j++ { + for h, w := range s { + if j < h { + break } + f[i][j] = max(f[i][j], f[i-1][j-h]+w) } } } - return dp[k] -} \ No newline at end of file + return f[n][k] +} diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.java b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.java index 6f533cb5a60da..78c809678253b 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.java +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.java @@ -1,25 +1,20 @@ class Solution { public int maxValueOfCoins(List> piles, int k) { int n = piles.size(); - List presum = new ArrayList<>(); - for (List p : piles) { - int m = p.size(); - int[] s = new int[m + 1]; - for (int i = 0; i < m; ++i) { - s[i + 1] = s[i] + p.get(i); + int[][] f = new int[n + 1][k + 1]; + for (int i = 1; i <= n; i++) { + List nums = piles.get(i - 1); + int[] s = new int[nums.size() + 1]; + s[0] = 0; + for (int j = 1; j <= nums.size(); j++) { + s[j] = s[j - 1] + nums.get(j - 1); } - presum.add(s); - } - int[] dp = new int[k + 1]; - for (int[] s : presum) { - for (int j = k; j >= 0; --j) { - for (int idx = 0; idx < s.length; ++idx) { - if (j >= idx) { - dp[j] = Math.max(dp[j], dp[j - idx] + s[idx]); - } + for (int j = 0; j <= k; j++) { + for (int h = 0; h < s.length && h <= j; h++) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - h] + s[h]); } } } - return dp[k]; + return f[n][k]; } -} \ No newline at end of file +} diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.py b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.py index 7f5d6a9004b4f..52ad882e77bd3 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.py +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.py @@ -1,11 +1,12 @@ class Solution: def maxValueOfCoins(self, piles: List[List[int]], k: int) -> int: - presum = [list(accumulate(p, initial=0)) for p in piles] n = len(piles) - dp = [[0] * (k + 1) for _ in range(n + 1)] - for i, s in enumerate(presum, 1): + f = [[0] * (k + 1) for _ in range(n + 1)] + for i, nums in enumerate(piles, 1): + s = list(accumulate(nums, initial=0)) for j in range(k + 1): - for idx, v in enumerate(s): - if j >= idx: - dp[i][j] = max(dp[i][j], dp[i - 1][j - idx] + v) - return dp[-1][-1] + for h, w in enumerate(s): + if j < h: + break + f[i][j] = max(f[i][j], f[i - 1][j - h] + w) + return f[n][k] diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.ts b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.ts new file mode 100644 index 0000000000000..155bd8bc99434 --- /dev/null +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution.ts @@ -0,0 +1,17 @@ +function maxValueOfCoins(piles: number[][], k: number): number { + const n = piles.length; + const f: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0)); + for (let i = 1; i <= n; i++) { + const nums = piles[i - 1]; + const s = Array(nums.length + 1).fill(0); + for (let j = 1; j <= nums.length; j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (let j = 0; j <= k; j++) { + for (let h = 0; h < s.length && h <= j; h++) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - h] + s[h]); + } + } + } + return f[n][k]; +} diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.cpp b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.cpp new file mode 100644 index 0000000000000..c900168ee60dc --- /dev/null +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.cpp @@ -0,0 +1,18 @@ +class Solution { +public: + int maxValueOfCoins(vector>& piles, int k) { + vector f(k + 1); + for (auto& nums : piles) { + vector s(nums.size() + 1); + for (int j = 1; j <= nums.size(); ++j) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (int j = k; j >= 0; --j) { + for (int h = 0; h < s.size() && h <= j; ++h) { + f[j] = max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; + } +}; diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.go b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.go new file mode 100644 index 0000000000000..e943849ba61e7 --- /dev/null +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.go @@ -0,0 +1,15 @@ +func maxValueOfCoins(piles [][]int, k int) int { + f := make([]int, k+1) + for _, nums := range piles { + s := make([]int, len(nums)+1) + for j := 1; j <= len(nums); j++ { + s[j] = s[j-1] + nums[j-1] + } + for j := k; j >= 0; j-- { + for h := 0; h < len(s) && h <= j; h++ { + f[j] = max(f[j], f[j-h]+s[h]) + } + } + } + return f[k] +} diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.java b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.java new file mode 100644 index 0000000000000..9e0b71397df09 --- /dev/null +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.java @@ -0,0 +1,17 @@ +class Solution { + public int maxValueOfCoins(List> piles, int k) { + int[] f = new int[k + 1]; + for (var nums : piles) { + int[] s = new int[nums.size() + 1]; + for (int j = 1; j <= nums.size(); ++j) { + s[j] = s[j - 1] + nums.get(j - 1); + } + for (int j = k; j >= 0; --j) { + for (int h = 0; h < s.length && h <= j; ++h) { + f[j] = Math.max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; + } +} diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.py b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.py index cbf2272622475..635ebd02fa511 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.py +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.py @@ -1,10 +1,11 @@ class Solution: def maxValueOfCoins(self, piles: List[List[int]], k: int) -> int: - presum = [list(accumulate(p, initial=0)) for p in piles] - dp = [0] * (k + 1) - for s in presum: + f = [0] * (k + 1) + for nums in piles: + s = list(accumulate(nums, initial=0)) for j in range(k, -1, -1): - for idx, v in enumerate(s): - if j >= idx: - dp[j] = max(dp[j], dp[j - idx] + v) - return dp[-1] + for h, w in enumerate(s): + if j < h: + break + f[j] = max(f[j], f[j - h] + w) + return f[k] diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.ts b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.ts new file mode 100644 index 0000000000000..f058fb6638930 --- /dev/null +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/Solution2.ts @@ -0,0 +1,15 @@ +function maxValueOfCoins(piles: number[][], k: number): number { + const f: number[] = Array(k + 1).fill(0); + for (const nums of piles) { + const s: number[] = Array(nums.length + 1).fill(0); + for (let j = 1; j <= nums.length; j++) { + s[j] = s[j - 1] + nums[j - 1]; + } + for (let j = k; j >= 0; j--) { + for (let h = 0; h < s.length && h <= j; h++) { + f[j] = Math.max(f[j], f[j - h] + s[h]); + } + } + } + return f[k]; +} From 206715f15f5088ef9820cfba57c890d5e3dba21d Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 21 Jan 2025 09:45:50 +0800 Subject: [PATCH 2/2] fix: solution --- .../2218.Maximum Value of K Coins From Piles/README.md | 6 +++++- .../2218.Maximum Value of K Coins From Piles/README_EN.md | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README.md b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README.md index f929b08451b73..8870635625a9a 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README.md +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README.md @@ -208,7 +208,11 @@ function maxValueOfCoins(piles: number[][], k: number): number { -### 方法二 +### 方法二:动态规划(空间优化) + +我们可以发现,对于第 $i$ 组,我们只需要用到 $f[i - 1][j]$ 和 $f[i][j - h]$,因此我们可以将二维数组优化为一维数组。 + +时间复杂度 $O(k \times L)$,空间复杂度 $O(k)$。 diff --git a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README_EN.md b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README_EN.md index 5d72cb2cea20c..30db6ab9b113c 100644 --- a/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README_EN.md +++ b/solution/2200-2299/2218.Maximum Value of K Coins From Piles/README_EN.md @@ -204,7 +204,11 @@ function maxValueOfCoins(piles: number[][], k: number): number { -### Solution 2 +### Solution 2: Dynamic Programming (Space Optimization) + +We can observe that for the $i$-th pile, we only need to use $f[i - 1][j]$ and $f[i][j - h]$, so we can optimize the two-dimensional array to a one-dimensional array. + +The time complexity is $O(k \times L)$, and the space complexity is $O(k)$.