diff --git a/solution/2700-2799/2735.Collecting Chocolates/README.md b/solution/2700-2799/2735.Collecting Chocolates/README.md index 9f5d39de973c5..2123b1e7f218d 100644 --- a/solution/2700-2799/2735.Collecting Chocolates/README.md +++ b/solution/2700-2799/2735.Collecting Chocolates/README.md @@ -53,25 +53,27 @@ **方法一:枚举** -我们考虑枚举操作的次数,定义 $f[i][j]$ 表示类型为 $i$ 的巧克力进行了 $j$ 次操作后的最小成本。那么有: +我们考虑枚举操作的次数,定义 $f[i][j]$ 表示类型为 $i$ 的巧克力进行了 $j$ 次操作后的最小成本。 + +对于类型为 $i$ 的巧克力: + +- 如果 $j = 0$,即没有进行操作,那么 $f[i][j] = nums[i]$; +- 如果 $0 \lt j \leq n-1$,那么它的最小成本就是下标范围为 $[i,.. (i + j) \bmod n]$ 的巧克力的最小成本,即 $f[i][j] = \min\{nums[i], nums[i + 1], \cdots, nums[(i + j) \bmod n]\}$,或者可以写成 $f[i][j] = \min\{f[i][j - 1], nums[(i + j) \bmod n]\}$。 +- 如果 $j \ge n$,由于当 $j = n - 1$ 时,已经覆盖了所有巧克力的最小成本,如果 $j$ 继续增大,那么最小成本不会再变化,但是操作次数的增加却会导致最终的成本增加,因此,我们不需要考虑 $j \ge n$ 的情况。 + +综上,我们可以得到状态转移方程: $$ f[i][j] = \begin{cases} nums[i] ,& j = 0 \\ -\min(f[i][j - 1], nums[(i + j) \bmod n]) ,& j > 0 +\min(f[i][j - 1], nums[(i + j) \bmod n]) ,& 0 \lt j \leq n - 1 \end{cases} $$ -接下来,我们枚举操作的次数 $j$,其中 $j \in [0,..n-1]$,那么进行 $j$ 次操作的最小成本为: - -$$ -\sum_{i=0}^{n-1} f[i][j] + j \times x -$$ - -我们取所有操作次数中的最小值即可。 +最后,我们只需要枚举操作的次数 $j$,计算出每种操作次数下的最小成本,取最小值即可。即答案为 $\min\limits_{0 \leq j \leq n - 1} \sum\limits_{i = 0}^{n - 1} f[i][j] + x \times j$。 -时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是数组 $nums$ 的长度。 +时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组 $nums$ 的长度。 @@ -88,11 +90,7 @@ class Solution: f[i][0] = v for j in range(1, n): f[i][j] = min(f[i][j - 1], nums[(i + j) % n]) - ans = inf - for j in range(n): - cost = sum(f[i][j] for i in range(n)) + x * j - ans = min(ans, cost) - return ans + return min(sum(f[i][j] for i in range(n)) + x * j for j in range(n)) ``` ### **Java** @@ -112,7 +110,7 @@ class Solution { } long ans = 1L << 60; for (int j = 0; j < n; ++j) { - long cost = 1L * j * x; + long cost = 1L * x * j; for (int i = 0; i < n; ++i) { cost += f[i][j]; } @@ -139,7 +137,7 @@ public: } long long ans = 1LL << 60; for (int j = 0; j < n; ++j) { - long long cost = 1LL * j * x; + long long cost = 1LL * x * j; for (int i = 0; i < n; ++i) { cost += f[i][j]; } @@ -156,9 +154,9 @@ public: func minCost(nums []int, x int) int64 { n := len(nums) f := make([][]int, n) - for i := range f { + for i, v := range nums { f[i] = make([]int, n) - f[i][0] = nums[i] + f[i][0] = v for j := 1; j < n; j++ { f[i][j] = min(f[i][j-1], nums[(i+j)%n]) } @@ -166,7 +164,7 @@ func minCost(nums []int, x int) int64 { ans := 1 << 60 for j := 0; j < n; j++ { cost := x * j - for i := range nums { + for i := 0; i < n; i++ { cost += f[i][j] } ans = min(ans, cost) @@ -175,6 +173,56 @@ func minCost(nums []int, x int) int64 { } ``` +### **TypeScript** + +```ts +function minCost(nums: number[], x: number): number { + const n = nums.length; + const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0)); + for (let i = 0; i < n; ++i) { + f[i][0] = nums[i]; + for (let j = 1; j < n; ++j) { + f[i][j] = Math.min(f[i][j - 1], nums[(i + j) % n]); + } + } + let ans = Infinity; + for (let j = 0; j < n; ++j) { + let cost = x * j; + for (let i = 0; i < n; ++i) { + cost += f[i][j]; + } + ans = Math.min(ans, cost); + } + return ans; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn min_cost(nums: Vec, x: i32) -> i64 { + let n = nums.len(); + let mut f = vec![vec![0; n]; n]; + for i in 0..n { + f[i][0] = nums[i]; + for j in 1..n { + f[i][j] = f[i][j - 1].min(nums[(i + j) % n]); + } + } + let mut ans = i64::MAX; + for j in 0..n { + let mut cost = (x as i64) * (j as i64); + for i in 0..n { + cost += f[i][j] as i64; + } + ans = ans.min(cost); + } + ans + } +} +``` + ### **...** ``` diff --git a/solution/2700-2799/2735.Collecting Chocolates/README_EN.md b/solution/2700-2799/2735.Collecting Chocolates/README_EN.md index 422848713ca4d..4af1950e952aa 100644 --- a/solution/2700-2799/2735.Collecting Chocolates/README_EN.md +++ b/solution/2700-2799/2735.Collecting Chocolates/README_EN.md @@ -45,6 +45,30 @@ Thus, the total cost will become (1 + 5 + 1 + 5 + 1) = 13. We can prove that thi ## Solutions +**Solution 1: Enumeration** + +We consider enumerating the number of operations, and define $f[i][j]$ as the minimum cost after performing $j$ operations on the chocolate of type $i$. + +For the chocolate of type $i$: + +- If $j = 0$, i.e., no operation is performed, then $f[i][j] = nums[i]$; +- If $0 \lt j \leq n-1$, then its minimum cost is the minimum cost of the chocolates with indices in the range $[i,.. (i + j) \bmod n]$, i.e., $f[i][j] = \min\{nums[i], nums[i + 1], \cdots, nums[(i + j) \bmod n]\}$, or it can be written as $f[i][j] = \min\{f[i][j - 1], nums[(i + j) \bmod n]\}$. +- If $j \ge n$, since when $j = n - 1$, the minimum cost of all covered chocolates has been obtained. If $j$ continues to increase, the minimum cost will not change, but the increase in the number of operations will lead to an increase in the final cost. Therefore, we do not need to consider the case where $j \ge n$. + +In summary, we can get the state transition equation: + +$$ +f[i][j] = +\begin{cases} +nums[i] ,& j = 0 \\ +\min(f[i][j - 1], nums[(i + j) \bmod n]) ,& 0 \lt j \leq n - 1 +\end{cases} +$$ + +Finally, we only need to enumerate the number of operations $j$, calculate the minimum cost under each number of operations, and take the minimum value. That is, the answer is $\min\limits_{0 \leq j \leq n - 1} \sum\limits_{i = 0}^{n - 1} f[i][j] + x \times j$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Where $n$ is the length of the array $nums$. + ### **Python3** @@ -58,11 +82,7 @@ class Solution: f[i][0] = v for j in range(1, n): f[i][j] = min(f[i][j - 1], nums[(i + j) % n]) - ans = inf - for j in range(n): - cost = sum(f[i][j] for i in range(n)) + x * j - ans = min(ans, cost) - return ans + return min(sum(f[i][j] for i in range(n)) + x * j for j in range(n)) ``` ### **Java** @@ -80,7 +100,7 @@ class Solution { } long ans = 1L << 60; for (int j = 0; j < n; ++j) { - long cost = 1L * j * x; + long cost = 1L * x * j; for (int i = 0; i < n; ++i) { cost += f[i][j]; } @@ -107,7 +127,7 @@ public: } long long ans = 1LL << 60; for (int j = 0; j < n; ++j) { - long long cost = 1LL * j * x; + long long cost = 1LL * x * j; for (int i = 0; i < n; ++i) { cost += f[i][j]; } @@ -124,9 +144,9 @@ public: func minCost(nums []int, x int) int64 { n := len(nums) f := make([][]int, n) - for i := range f { + for i, v := range nums { f[i] = make([]int, n) - f[i][0] = nums[i] + f[i][0] = v for j := 1; j < n; j++ { f[i][j] = min(f[i][j-1], nums[(i+j)%n]) } @@ -134,7 +154,7 @@ func minCost(nums []int, x int) int64 { ans := 1 << 60 for j := 0; j < n; j++ { cost := x * j - for i := range nums { + for i := 0; i < n; i++ { cost += f[i][j] } ans = min(ans, cost) @@ -143,6 +163,56 @@ func minCost(nums []int, x int) int64 { } ``` +### **TypeScript** + +```ts +function minCost(nums: number[], x: number): number { + const n = nums.length; + const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0)); + for (let i = 0; i < n; ++i) { + f[i][0] = nums[i]; + for (let j = 1; j < n; ++j) { + f[i][j] = Math.min(f[i][j - 1], nums[(i + j) % n]); + } + } + let ans = Infinity; + for (let j = 0; j < n; ++j) { + let cost = x * j; + for (let i = 0; i < n; ++i) { + cost += f[i][j]; + } + ans = Math.min(ans, cost); + } + return ans; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn min_cost(nums: Vec, x: i32) -> i64 { + let n = nums.len(); + let mut f = vec![vec![0; n]; n]; + for i in 0..n { + f[i][0] = nums[i]; + for j in 1..n { + f[i][j] = f[i][j - 1].min(nums[(i + j) % n]); + } + } + let mut ans = i64::MAX; + for j in 0..n { + let mut cost = (x as i64) * (j as i64); + for i in 0..n { + cost += f[i][j] as i64; + } + ans = ans.min(cost); + } + ans + } +} +``` + ### **...** ``` diff --git a/solution/2700-2799/2735.Collecting Chocolates/Solution.cpp b/solution/2700-2799/2735.Collecting Chocolates/Solution.cpp index 77f2990150607..971687a6e1dbb 100644 --- a/solution/2700-2799/2735.Collecting Chocolates/Solution.cpp +++ b/solution/2700-2799/2735.Collecting Chocolates/Solution.cpp @@ -1,22 +1,22 @@ -class Solution { -public: - long long minCost(vector& nums, int x) { - int n = nums.size(); - int f[n][n]; - for (int i = 0; i < n; ++i) { - f[i][0] = nums[i]; - for (int j = 1; j < n; ++j) { - f[i][j] = min(f[i][j - 1], nums[(i + j) % n]); - } - } - long long ans = 1LL << 60; - for (int j = 0; j < n; ++j) { - long long cost = 1LL * j * x; - for (int i = 0; i < n; ++i) { - cost += f[i][j]; - } - ans = min(ans, cost); - } - return ans; - } +class Solution { +public: + long long minCost(vector& nums, int x) { + int n = nums.size(); + int f[n][n]; + for (int i = 0; i < n; ++i) { + f[i][0] = nums[i]; + for (int j = 1; j < n; ++j) { + f[i][j] = min(f[i][j - 1], nums[(i + j) % n]); + } + } + long long ans = 1LL << 60; + for (int j = 0; j < n; ++j) { + long long cost = 1LL * x * j; + for (int i = 0; i < n; ++i) { + cost += f[i][j]; + } + ans = min(ans, cost); + } + return ans; + } }; \ No newline at end of file diff --git a/solution/2700-2799/2735.Collecting Chocolates/Solution.go b/solution/2700-2799/2735.Collecting Chocolates/Solution.go index e76aa34c8a6f7..a62e16a70a1c7 100644 --- a/solution/2700-2799/2735.Collecting Chocolates/Solution.go +++ b/solution/2700-2799/2735.Collecting Chocolates/Solution.go @@ -1,9 +1,9 @@ func minCost(nums []int, x int) int64 { n := len(nums) f := make([][]int, n) - for i := range f { + for i, v := range nums { f[i] = make([]int, n) - f[i][0] = nums[i] + f[i][0] = v for j := 1; j < n; j++ { f[i][j] = min(f[i][j-1], nums[(i+j)%n]) } @@ -11,7 +11,7 @@ func minCost(nums []int, x int) int64 { ans := 1 << 60 for j := 0; j < n; j++ { cost := x * j - for i := range nums { + for i := 0; i < n; i++ { cost += f[i][j] } ans = min(ans, cost) diff --git a/solution/2700-2799/2735.Collecting Chocolates/Solution.java b/solution/2700-2799/2735.Collecting Chocolates/Solution.java index def68bfc0408b..0e1c75f244ce0 100644 --- a/solution/2700-2799/2735.Collecting Chocolates/Solution.java +++ b/solution/2700-2799/2735.Collecting Chocolates/Solution.java @@ -1,21 +1,21 @@ -class Solution { - public long minCost(int[] nums, int x) { - int n = nums.length; - int[][] f = new int[n][n]; - for (int i = 0; i < n; ++i) { - f[i][0] = nums[i]; - for (int j = 1; j < n; ++j) { - f[i][j] = Math.min(f[i][j - 1], nums[(i + j) % n]); - } - } - long ans = 1L << 60; - for (int j = 0; j < n; ++j) { - long cost = 1L * j * x; - for (int i = 0; i < n; ++i) { - cost += f[i][j]; - } - ans = Math.min(ans, cost); - } - return ans; - } +class Solution { + public long minCost(int[] nums, int x) { + int n = nums.length; + int[][] f = new int[n][n]; + for (int i = 0; i < n; ++i) { + f[i][0] = nums[i]; + for (int j = 1; j < n; ++j) { + f[i][j] = Math.min(f[i][j - 1], nums[(i + j) % n]); + } + } + long ans = 1L << 60; + for (int j = 0; j < n; ++j) { + long cost = 1L * x * j; + for (int i = 0; i < n; ++i) { + cost += f[i][j]; + } + ans = Math.min(ans, cost); + } + return ans; + } } \ No newline at end of file diff --git a/solution/2700-2799/2735.Collecting Chocolates/Solution.py b/solution/2700-2799/2735.Collecting Chocolates/Solution.py index 983ed7fd02e8d..48ebe53a46246 100644 --- a/solution/2700-2799/2735.Collecting Chocolates/Solution.py +++ b/solution/2700-2799/2735.Collecting Chocolates/Solution.py @@ -1,13 +1,9 @@ -class Solution: - def minCost(self, nums: List[int], x: int) -> int: - n = len(nums) - f = [[0] * n for _ in range(n)] - for i, v in enumerate(nums): - f[i][0] = v - for j in range(1, n): - f[i][j] = min(f[i][j - 1], nums[(i + j) % n]) - ans = inf - for j in range(n): - cost = sum(f[i][j] for i in range(n)) + x * j - ans = min(ans, cost) - return ans +class Solution: + def minCost(self, nums: List[int], x: int) -> int: + n = len(nums) + f = [[0] * n for _ in range(n)] + for i, v in enumerate(nums): + f[i][0] = v + for j in range(1, n): + f[i][j] = min(f[i][j - 1], nums[(i + j) % n]) + return min(sum(f[i][j] for i in range(n)) + x * j for j in range(n)) diff --git a/solution/2700-2799/2735.Collecting Chocolates/Solution.rs b/solution/2700-2799/2735.Collecting Chocolates/Solution.rs new file mode 100644 index 0000000000000..037aec5fa0484 --- /dev/null +++ b/solution/2700-2799/2735.Collecting Chocolates/Solution.rs @@ -0,0 +1,21 @@ +impl Solution { + pub fn min_cost(nums: Vec, x: i32) -> i64 { + let n = nums.len(); + let mut f = vec![vec![0; n]; n]; + for i in 0..n { + f[i][0] = nums[i]; + for j in 1..n { + f[i][j] = f[i][j - 1].min(nums[(i + j) % n]); + } + } + let mut ans = i64::MAX; + for j in 0..n { + let mut cost = (x as i64) * (j as i64); + for i in 0..n { + cost += f[i][j] as i64; + } + ans = ans.min(cost); + } + ans + } +} diff --git a/solution/2700-2799/2735.Collecting Chocolates/Solution.ts b/solution/2700-2799/2735.Collecting Chocolates/Solution.ts new file mode 100644 index 0000000000000..bc513852c19db --- /dev/null +++ b/solution/2700-2799/2735.Collecting Chocolates/Solution.ts @@ -0,0 +1,19 @@ +function minCost(nums: number[], x: number): number { + const n = nums.length; + const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0)); + for (let i = 0; i < n; ++i) { + f[i][0] = nums[i]; + for (let j = 1; j < n; ++j) { + f[i][j] = Math.min(f[i][j - 1], nums[(i + j) % n]); + } + } + let ans = Infinity; + for (let j = 0; j < n; ++j) { + let cost = x * j; + for (let i = 0; i < n; ++i) { + cost += f[i][j]; + } + ans = Math.min(ans, cost); + } + return ans; +}