diff --git a/solution/3600-3699/3693.Climbing Stairs II/README.md b/solution/3600-3699/3693.Climbing Stairs II/README.md index f0d6348f3ddfa..a0c5e7b3c4979 100644 --- a/solution/3600-3699/3693.Climbing Stairs II/README.md +++ b/solution/3600-3699/3693.Climbing Stairs II/README.md @@ -133,32 +133,134 @@ source: 第 166 场双周赛 Q2 -### 方法一 +### 方法一:动态规划 + +我们定义 $f[i]$ 表示到达第 $i$ 级台阶所需的最小总成本,初始时 $f[0] = 0$,其余 $f[i] = +\infty$。 + +对于每一级台阶 $i$,我们可以从第 $i-1$ 级、第 $i-2$ 级或第 $i-3$ 级台阶跳跃过来,因此我们有以下状态转移方程: + +$$ +f[i] = \min_{j=i-3}^{i-1} (f[j] + \textit{costs}[i - 1] + (i - j)^2) +$$ + +其中 $\textit{costs}[i]$ 是第 $i$ 级台阶的成本,$(i - j)^2$ 是从第 $j$ 级台阶跳到第 $i$ 级台阶的跳跃成本。注意,我们需要确保 $j$ 不小于 $0$。 + +最终答案为 $f[n]$。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$,其中 $n$ 是台阶的数量。 #### Python3 ```python - +class Solution: + def climbStairs(self, n: int, costs: List[int]) -> int: + n = len(costs) + f = [inf] * (n + 1) + f[0] = 0 + for i, x in enumerate(costs, 1): + for j in range(i - 3, i): + if j >= 0: + f[i] = min(f[i], f[j] + x + (i - j) ** 2) + return f[n] ``` #### Java ```java - +class Solution { + public int climbStairs(int n, int[] costs) { + int[] f = new int[n + 1]; + final int inf = Integer.MAX_VALUE / 2; + Arrays.fill(f, inf); + f[0] = 0; + for (int i = 1; i <= n; ++i) { + int x = costs[i - 1]; + for (int j = Math.max(0, i - 3); j < i; ++j) { + f[i] = Math.min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int climbStairs(int n, vector& costs) { + vector f(n + 1, INT_MAX / 2); + f[0] = 0; + for (int i = 1; i <= n; ++i) { + int x = costs[i - 1]; + for (int j = max(0, i - 3); j < i; ++j) { + f[i] = min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; + } +}; ``` #### Go ```go +func climbStairs(n int, costs []int) int { + const inf = int(1e9) + f := make([]int, n+1) + for i := range f { + f[i] = inf + } + f[0] = 0 + for i := 1; i <= n; i++ { + x := costs[i-1] + for j := max(0, i-3); j < i; j++ { + f[i] = min(f[i], f[j]+x+(i-j)*(i-j)) + } + } + return f[n] +} +``` + +#### TypeScript + +```ts +function climbStairs(n: number, costs: number[]): number { + const inf = Number.MAX_SAFE_INTEGER / 2; + const f = Array(n + 1).fill(inf); + f[0] = 0; + + for (let i = 1; i <= n; ++i) { + const x = costs[i - 1]; + for (let j = Math.max(0, i - 3); j < i; ++j) { + f[i] = Math.min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; +} +``` +#### Rust + +```rust +impl Solution { + pub fn climb_stairs(n: i32, costs: Vec) -> i32 { + let n = n as usize; + let inf = i32::MAX / 2; + let mut f = vec![inf; n + 1]; + f[0] = 0; + for i in 1..=n { + let x = costs[i - 1]; + for j in (i.saturating_sub(3))..i { + f[i] = f[i].min(f[j] + x + ((i - j) * (i - j)) as i32); + } + } + f[n] + } +} ``` diff --git a/solution/3600-3699/3693.Climbing Stairs II/README_EN.md b/solution/3600-3699/3693.Climbing Stairs II/README_EN.md index 5ebb8553820af..6e6590288a3d0 100644 --- a/solution/3600-3699/3693.Climbing Stairs II/README_EN.md +++ b/solution/3600-3699/3693.Climbing Stairs II/README_EN.md @@ -130,32 +130,134 @@ source: Biweekly Contest 166 Q2 -### Solution 1 +### Solution 1: Dynamic Programming + +We define $f[i]$ as the minimum total cost required to reach the $i$-th stair, initially $f[0] = 0$, and all other $f[i] = +\infty$. + +For each stair $i$, we can jump from the $(i-1)$-th, $(i-2)$-th, or $(i-3)$-th stair, so we have the following state transition equation: + +$$ +f[i] = \min_{j=i-3}^{i-1} (f[j] + \textit{costs}[i - 1] + (i - j)^2) +$$ + +Where $\textit{costs}[i]$ is the cost of the $i$-th stair, and $(i - j)^2$ is the jump cost from the $j$-th stair to the $i$-th stair. Note that we need to ensure $j$ is not less than $0$. + +The final answer is $f[n]$. + +The time complexity is $O(n)$ and the space complexity is $O(n)$, where $n$ is the number of stairs. #### Python3 ```python - +class Solution: + def climbStairs(self, n: int, costs: List[int]) -> int: + n = len(costs) + f = [inf] * (n + 1) + f[0] = 0 + for i, x in enumerate(costs, 1): + for j in range(i - 3, i): + if j >= 0: + f[i] = min(f[i], f[j] + x + (i - j) ** 2) + return f[n] ``` #### Java ```java - +class Solution { + public int climbStairs(int n, int[] costs) { + int[] f = new int[n + 1]; + final int inf = Integer.MAX_VALUE / 2; + Arrays.fill(f, inf); + f[0] = 0; + for (int i = 1; i <= n; ++i) { + int x = costs[i - 1]; + for (int j = Math.max(0, i - 3); j < i; ++j) { + f[i] = Math.min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int climbStairs(int n, vector& costs) { + vector f(n + 1, INT_MAX / 2); + f[0] = 0; + for (int i = 1; i <= n; ++i) { + int x = costs[i - 1]; + for (int j = max(0, i - 3); j < i; ++j) { + f[i] = min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; + } +}; ``` #### Go ```go +func climbStairs(n int, costs []int) int { + const inf = int(1e9) + f := make([]int, n+1) + for i := range f { + f[i] = inf + } + f[0] = 0 + for i := 1; i <= n; i++ { + x := costs[i-1] + for j := max(0, i-3); j < i; j++ { + f[i] = min(f[i], f[j]+x+(i-j)*(i-j)) + } + } + return f[n] +} +``` + +#### TypeScript + +```ts +function climbStairs(n: number, costs: number[]): number { + const inf = Number.MAX_SAFE_INTEGER / 2; + const f = Array(n + 1).fill(inf); + f[0] = 0; + + for (let i = 1; i <= n; ++i) { + const x = costs[i - 1]; + for (let j = Math.max(0, i - 3); j < i; ++j) { + f[i] = Math.min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; +} +``` +#### Rust + +```rust +impl Solution { + pub fn climb_stairs(n: i32, costs: Vec) -> i32 { + let n = n as usize; + let inf = i32::MAX / 2; + let mut f = vec![inf; n + 1]; + f[0] = 0; + for i in 1..=n { + let x = costs[i - 1]; + for j in (i.saturating_sub(3))..i { + f[i] = f[i].min(f[j] + x + ((i - j) * (i - j)) as i32); + } + } + f[n] + } +} ``` diff --git a/solution/3600-3699/3693.Climbing Stairs II/Solution.cpp b/solution/3600-3699/3693.Climbing Stairs II/Solution.cpp new file mode 100644 index 0000000000000..17ae861cfb350 --- /dev/null +++ b/solution/3600-3699/3693.Climbing Stairs II/Solution.cpp @@ -0,0 +1,14 @@ +class Solution { +public: + int climbStairs(int n, vector& costs) { + vector f(n + 1, INT_MAX / 2); + f[0] = 0; + for (int i = 1; i <= n; ++i) { + int x = costs[i - 1]; + for (int j = max(0, i - 3); j < i; ++j) { + f[i] = min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; + } +}; diff --git a/solution/3600-3699/3693.Climbing Stairs II/Solution.go b/solution/3600-3699/3693.Climbing Stairs II/Solution.go new file mode 100644 index 0000000000000..43c16ba8fb2c4 --- /dev/null +++ b/solution/3600-3699/3693.Climbing Stairs II/Solution.go @@ -0,0 +1,15 @@ +func climbStairs(n int, costs []int) int { + const inf = int(1e9) + f := make([]int, n+1) + for i := range f { + f[i] = inf + } + f[0] = 0 + for i := 1; i <= n; i++ { + x := costs[i-1] + for j := max(0, i-3); j < i; j++ { + f[i] = min(f[i], f[j]+x+(i-j)*(i-j)) + } + } + return f[n] +} diff --git a/solution/3600-3699/3693.Climbing Stairs II/Solution.java b/solution/3600-3699/3693.Climbing Stairs II/Solution.java new file mode 100644 index 0000000000000..aa191e143b583 --- /dev/null +++ b/solution/3600-3699/3693.Climbing Stairs II/Solution.java @@ -0,0 +1,15 @@ +class Solution { + public int climbStairs(int n, int[] costs) { + int[] f = new int[n + 1]; + final int inf = Integer.MAX_VALUE / 2; + Arrays.fill(f, inf); + f[0] = 0; + for (int i = 1; i <= n; ++i) { + int x = costs[i - 1]; + for (int j = Math.max(0, i - 3); j < i; ++j) { + f[i] = Math.min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; + } +} diff --git a/solution/3600-3699/3693.Climbing Stairs II/Solution.py b/solution/3600-3699/3693.Climbing Stairs II/Solution.py new file mode 100644 index 0000000000000..03c15ba6775ec --- /dev/null +++ b/solution/3600-3699/3693.Climbing Stairs II/Solution.py @@ -0,0 +1,10 @@ +class Solution: + def climbStairs(self, n: int, costs: List[int]) -> int: + n = len(costs) + f = [inf] * (n + 1) + f[0] = 0 + for i, x in enumerate(costs, 1): + for j in range(i - 3, i): + if j >= 0: + f[i] = min(f[i], f[j] + x + (i - j) ** 2) + return f[n] diff --git a/solution/3600-3699/3693.Climbing Stairs II/Solution.rs b/solution/3600-3699/3693.Climbing Stairs II/Solution.rs new file mode 100644 index 0000000000000..a0e7c071b709e --- /dev/null +++ b/solution/3600-3699/3693.Climbing Stairs II/Solution.rs @@ -0,0 +1,15 @@ +impl Solution { + pub fn climb_stairs(n: i32, costs: Vec) -> i32 { + let n = n as usize; + let inf = i32::MAX / 2; + let mut f = vec![inf; n + 1]; + f[0] = 0; + for i in 1..=n { + let x = costs[i - 1]; + for j in (i.saturating_sub(3))..i { + f[i] = f[i].min(f[j] + x + ((i - j) * (i - j)) as i32); + } + } + f[n] + } +} diff --git a/solution/3600-3699/3693.Climbing Stairs II/Solution.ts b/solution/3600-3699/3693.Climbing Stairs II/Solution.ts new file mode 100644 index 0000000000000..04e37cc0adcb4 --- /dev/null +++ b/solution/3600-3699/3693.Climbing Stairs II/Solution.ts @@ -0,0 +1,13 @@ +function climbStairs(n: number, costs: number[]): number { + const inf = Number.MAX_SAFE_INTEGER / 2; + const f = Array(n + 1).fill(inf); + f[0] = 0; + + for (let i = 1; i <= n; ++i) { + const x = costs[i - 1]; + for (let j = Math.max(0, i - 3); j < i; ++j) { + f[i] = Math.min(f[i], f[j] + x + (i - j) * (i - j)); + } + } + return f[n]; +}