diff --git a/solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README.md b/solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README.md index f6e81fc472617..0364ba0edd60f 100644 --- a/solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README.md +++ b/solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README.md @@ -106,6 +106,24 @@ class Solution: return -1 ``` +```python +class Solution: + def minSkips(self, dist: List[int], speed: int, hoursBefore: int) -> int: + n = len(dist) + f = [[inf] * (n + 1) for _ in range(n + 1)] + f[0][0] = 0 + for i, x in enumerate(dist, 1): + for j in range(i + 1): + if j < i: + f[i][j] = min(f[i][j], ((f[i - 1][j] + x - 1) // speed + 1) * speed) + if j: + f[i][j] = min(f[i][j], f[i - 1][j - 1] + x) + for j in range(n + 1): + if f[n][j] <= hoursBefore * speed: + return j + return -1 +``` + ```java class Solution { public int minSkips(int[] dist, int speed, int hoursBefore) { @@ -223,28 +241,4 @@ function minSkips(dist: number[], speed: number, hoursBefore: number): number { -### 方法二 - - - -```python -class Solution: - def minSkips(self, dist: List[int], speed: int, hoursBefore: int) -> int: - n = len(dist) - f = [[inf] * (n + 1) for _ in range(n + 1)] - f[0][0] = 0 - for i, x in enumerate(dist, 1): - for j in range(i + 1): - if j < i: - f[i][j] = min(f[i][j], ((f[i - 1][j] + x - 1) // speed + 1) * speed) - if j: - f[i][j] = min(f[i][j], f[i - 1][j - 1] + x) - for j in range(n + 1): - if f[n][j] <= hoursBefore * speed: - return j - return -1 -``` - - - diff --git a/solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README_EN.md b/solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README_EN.md index 2311dfa306772..cfaa3a3714350 100644 --- a/solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README_EN.md +++ b/solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README_EN.md @@ -65,7 +65,21 @@ You can skip the first and third rest to arrive in ((7/2 + 0) + (3/2 + 0) ## Solutions -### Solution 1 +### Solution 1: Dynamic Programming + +We define $f[i][j]$ as the shortest time considering the first $i$ roads and exactly skipping $j$ rest times. Initially, $f[0][0]=0$, and the rest $f[i][j]=\infty$. + +Since we can choose to skip or not skip the rest time of the $i$-th road, we can list the state transition equation: + +$$ +f[i][j]=\min\left\{\begin{aligned} \lceil f[i-1][j]+\frac{d_i}{s}\rceil & \text{Do not skip the rest time of the $i$-th road} \\ f[i-1][j-1]+\frac{d_i}{s} & \text{Skip the rest time of the $i$-th road} \end{aligned}\right. +$$ + +Where $\lceil x\rceil$ represents rounding $x$ up. It should be noted that since we need to ensure that exactly $j$ rest times are skipped, we must have $j\le i$; moreover, if $j=0$, no rest time can be skipped. + +Due to the possible precision error brought by floating-point operations and rounding up, we introduce a constant $eps = 10^{-8}$ to represent a very small positive real number. We subtract $eps$ before rounding the floating-point number, and finally, when comparing $f[n][j]$ and $hoursBefore$, we need to add $eps$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$, where $n$ is the number of roads. @@ -88,6 +102,24 @@ class Solution: return -1 ``` +```python +class Solution: + def minSkips(self, dist: List[int], speed: int, hoursBefore: int) -> int: + n = len(dist) + f = [[inf] * (n + 1) for _ in range(n + 1)] + f[0][0] = 0 + for i, x in enumerate(dist, 1): + for j in range(i + 1): + if j < i: + f[i][j] = min(f[i][j], ((f[i - 1][j] + x - 1) // speed + 1) * speed) + if j: + f[i][j] = min(f[i][j], f[i - 1][j - 1] + x) + for j in range(n + 1): + if f[n][j] <= hoursBefore * speed: + return j + return -1 +``` + ```java class Solution { public int minSkips(int[] dist, int speed, int hoursBefore) { @@ -205,28 +237,4 @@ function minSkips(dist: number[], speed: number, hoursBefore: number): number { -### Solution 2 - - - -```python -class Solution: - def minSkips(self, dist: List[int], speed: int, hoursBefore: int) -> int: - n = len(dist) - f = [[inf] * (n + 1) for _ in range(n + 1)] - f[0][0] = 0 - for i, x in enumerate(dist, 1): - for j in range(i + 1): - if j < i: - f[i][j] = min(f[i][j], ((f[i - 1][j] + x - 1) // speed + 1) * speed) - if j: - f[i][j] = min(f[i][j], f[i - 1][j - 1] + x) - for j in range(n + 1): - if f[n][j] <= hoursBefore * speed: - return j - return -1 -``` - - - diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README.md b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README.md index 1a410ea2f3d3b..9f54ed845cab3 100644 --- a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README.md +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README.md @@ -94,6 +94,8 @@ class Solution: t = min(budget // (k + 1), cnt[k]) ans += t * k budget -= t * (k + 1) + if budget == 0: + break cnt[k - 1] += cnt[k] - t return ans ``` @@ -114,7 +116,7 @@ class Solution { } } int ans = 0; - for (k = n - 1; k > 0; --k) { + for (k = n - 1; k > 0 && budget > 0; --k) { int t = Math.min(budget / (k + 1), cnt[k]); ans += t * k; budget -= t * (k + 1); @@ -142,7 +144,7 @@ public: } } int ans = 0; - for (k = n - 1; k; --k) { + for (k = n - 1; k && budget; --k) { int t = min(budget / (k + 1), cnt[k]); ans += t * k; budget -= t * (k + 1); @@ -167,7 +169,7 @@ func maxPotholes(road string, budget int) (ans int) { k = 0 } } - for k = n - 1; k > 0; k-- { + for k = n - 1; k > 0 && budget > 0; k-- { t := min(budget/(k+1), cnt[k]) ans += t * k budget -= t * (k + 1) @@ -192,7 +194,7 @@ function maxPotholes(road: string, budget: number): number { } } let ans = 0; - for (k = n - 1; k; --k) { + for (k = n - 1; k && budget; --k) { const t = Math.min(Math.floor(budget / (k + 1)), cnt[k]); ans += t * k; budget -= t * (k + 1); @@ -202,6 +204,69 @@ function maxPotholes(road: string, budget: number): number { } ``` +```rust +impl Solution { + pub fn max_potholes(road: String, budget: i32) -> i32 { + let mut cs: Vec = road.chars().collect(); + cs.push('.'); + let n = cs.len(); + let mut cnt: Vec = vec![0; n]; + let mut k = 0; + + for c in cs.iter() { + if *c == 'x' { + k += 1; + } else if k > 0 { + cnt[k] += 1; + k = 0; + } + } + + let mut ans = 0; + let mut budget = budget; + + for k in (1..n).rev() { + if budget == 0 { + break; + } + let t = std::cmp::min(budget / ((k as i32) + 1), cnt[k]); + ans += t * (k as i32); + budget -= t * ((k as i32) + 1); + cnt[k - 1] += cnt[k] - t; + } + + ans + } +} +``` + +```cs +public class Solution { + public int MaxPotholes(string road, int budget) { + road += '.'; + int n = road.Length; + int[] cnt = new int[n]; + int k = 0; + foreach (char c in road) { + if (c == 'x') { + ++k; + } else if (k > 0) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k > 0 && budget > 0; --k) { + int t = Math.Min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +} +``` + diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README_EN.md b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README_EN.md index a1c403c2ef5e2..a03ffd446acc7 100644 --- a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README_EN.md +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/README_EN.md @@ -92,6 +92,8 @@ class Solution: t = min(budget // (k + 1), cnt[k]) ans += t * k budget -= t * (k + 1) + if budget == 0: + break cnt[k - 1] += cnt[k] - t return ans ``` @@ -112,7 +114,7 @@ class Solution { } } int ans = 0; - for (k = n - 1; k > 0; --k) { + for (k = n - 1; k > 0 && budget > 0; --k) { int t = Math.min(budget / (k + 1), cnt[k]); ans += t * k; budget -= t * (k + 1); @@ -140,7 +142,7 @@ public: } } int ans = 0; - for (k = n - 1; k; --k) { + for (k = n - 1; k && budget; --k) { int t = min(budget / (k + 1), cnt[k]); ans += t * k; budget -= t * (k + 1); @@ -165,7 +167,7 @@ func maxPotholes(road string, budget int) (ans int) { k = 0 } } - for k = n - 1; k > 0; k-- { + for k = n - 1; k > 0 && budget > 0; k-- { t := min(budget/(k+1), cnt[k]) ans += t * k budget -= t * (k + 1) @@ -190,7 +192,7 @@ function maxPotholes(road: string, budget: number): number { } } let ans = 0; - for (k = n - 1; k; --k) { + for (k = n - 1; k && budget; --k) { const t = Math.min(Math.floor(budget / (k + 1)), cnt[k]); ans += t * k; budget -= t * (k + 1); @@ -200,6 +202,69 @@ function maxPotholes(road: string, budget: number): number { } ``` +```rust +impl Solution { + pub fn max_potholes(road: String, budget: i32) -> i32 { + let mut cs: Vec = road.chars().collect(); + cs.push('.'); + let n = cs.len(); + let mut cnt: Vec = vec![0; n]; + let mut k = 0; + + for c in cs.iter() { + if *c == 'x' { + k += 1; + } else if k > 0 { + cnt[k] += 1; + k = 0; + } + } + + let mut ans = 0; + let mut budget = budget; + + for k in (1..n).rev() { + if budget == 0 { + break; + } + let t = std::cmp::min(budget / ((k as i32) + 1), cnt[k]); + ans += t * (k as i32); + budget -= t * ((k as i32) + 1); + cnt[k - 1] += cnt[k] - t; + } + + ans + } +} +``` + +```cs +public class Solution { + public int MaxPotholes(string road, int budget) { + road += '.'; + int n = road.Length; + int[] cnt = new int[n]; + int k = 0; + foreach (char c in road) { + if (c == 'x') { + ++k; + } else if (k > 0) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k > 0 && budget > 0; --k) { + int t = Math.Min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +} +``` + diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cpp b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cpp index d7e0d2dba6f2e..b5e6411a0721a 100644 --- a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cpp +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cpp @@ -14,7 +14,7 @@ class Solution { } } int ans = 0; - for (k = n - 1; k; --k) { + for (k = n - 1; k && budget; --k) { int t = min(budget / (k + 1), cnt[k]); ans += t * k; budget -= t * (k + 1); diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cs b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cs new file mode 100644 index 0000000000000..64f9bfbe3e97c --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.cs @@ -0,0 +1,24 @@ +public class Solution { + public int MaxPotholes(string road, int budget) { + road += '.'; + int n = road.Length; + int[] cnt = new int[n]; + int k = 0; + foreach (char c in road) { + if (c == 'x') { + ++k; + } else if (k > 0) { + ++cnt[k]; + k = 0; + } + } + int ans = 0; + for (k = n - 1; k > 0 && budget > 0; --k) { + int t = Math.Min(budget / (k + 1), cnt[k]); + ans += t * k; + budget -= t * (k + 1); + cnt[k - 1] += cnt[k] - t; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.go b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.go index 252c6fdd8df4f..95d3fac8813e9 100644 --- a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.go +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.go @@ -11,7 +11,7 @@ func maxPotholes(road string, budget int) (ans int) { k = 0 } } - for k = n - 1; k > 0; k-- { + for k = n - 1; k > 0 && budget > 0; k-- { t := min(budget/(k+1), cnt[k]) ans += t * k budget -= t * (k + 1) diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.java b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.java index 83b83144db179..ab767ec3a36b5 100644 --- a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.java +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.java @@ -13,7 +13,7 @@ public int maxPotholes(String road, int budget) { } } int ans = 0; - for (k = n - 1; k > 0; --k) { + for (k = n - 1; k > 0 && budget > 0; --k) { int t = Math.min(budget / (k + 1), cnt[k]); ans += t * k; budget -= t * (k + 1); diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.py b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.py index acedd2b38186f..a5996a4087bf7 100644 --- a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.py +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.py @@ -17,5 +17,7 @@ def maxPotholes(self, road: str, budget: int) -> int: t = min(budget // (k + 1), cnt[k]) ans += t * k budget -= t * (k + 1) + if budget == 0: + break cnt[k - 1] += cnt[k] - t return ans diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.rs b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.rs new file mode 100644 index 0000000000000..c42391512aa07 --- /dev/null +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.rs @@ -0,0 +1,33 @@ +impl Solution { + pub fn max_potholes(road: String, budget: i32) -> i32 { + let mut cs: Vec = road.chars().collect(); + cs.push('.'); + let n = cs.len(); + let mut cnt: Vec = vec![0; n]; + let mut k = 0; + + for c in cs.iter() { + if *c == 'x' { + k += 1; + } else if k > 0 { + cnt[k] += 1; + k = 0; + } + } + + let mut ans = 0; + let mut budget = budget; + + for k in (1..n).rev() { + if budget == 0 { + break; + } + let t = std::cmp::min(budget / ((k as i32) + 1), cnt[k]); + ans += t * (k as i32); + budget -= t * ((k as i32) + 1); + cnt[k - 1] += cnt[k] - t; + } + + ans + } +} diff --git a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.ts b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.ts index 0d64e6ad69557..14043d0e812d4 100644 --- a/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.ts +++ b/solution/3100-3199/3119.Maximum Number of Potholes That Can Be Fixed/Solution.ts @@ -12,7 +12,7 @@ function maxPotholes(road: string, budget: number): number { } } let ans = 0; - for (k = n - 1; k; --k) { + for (k = n - 1; k && budget; --k) { const t = Math.min(Math.floor(budget / (k + 1)), cnt[k]); ans += t * k; budget -= t * (k + 1);