Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ebe805a

Browse files
feat: add solutions to lc problem: No.1690 (doocs#2298)
No.1690.Stone Game VII
1 parent 53fea67 commit ebe805a

File tree

9 files changed

+380
-3
lines changed

9 files changed

+380
-3
lines changed

‎solution/1600-1699/1690.Stone Game VII/README.md‎

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
class Solution:
7070
def stoneGameVII(self, stones: List[int]) -> int:
7171
@cache
72-
def dfs(i, j):
72+
def dfs(i: int, j: int) -> int:
7373
if i > j:
7474
return 0
7575
a = s[j + 1] - s[i + 1] - dfs(i + 1, j)
@@ -165,6 +165,143 @@ func stoneGameVII(stones []int) int {
165165
}
166166
```
167167

168+
```ts
169+
function stoneGameVII(stones: number[]): number {
170+
const n = stones.length;
171+
const s: number[] = Array(n + 1).fill(0);
172+
for (let i = 0; i < n; ++i) {
173+
s[i + 1] = s[i] + stones[i];
174+
}
175+
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
176+
const dfs = (i: number, j: number): number => {
177+
if (i > j) {
178+
return 0;
179+
}
180+
if (f[i][j]) {
181+
return f[i][j];
182+
}
183+
const a = s[j + 1] - s[i + 1] - dfs(i + 1, j);
184+
const b = s[j] - s[i] - dfs(i, j - 1);
185+
return (f[i][j] = Math.max(a, b));
186+
};
187+
return dfs(0, n - 1);
188+
}
189+
```
190+
168191
<!-- tabs:end -->
169192

193+
### 方法二:动态规划
194+
195+
我们可以将方法一中的记忆化搜索转换为动态规划,定义 $f[i][j]$ 表示当剩下的石子为 $stones[i], stones[i + 1], \dots, stones[j]$ 时,先手与后手的得分差值。那么答案即为 $f[0][n - 1]$。
196+
197+
状态转移方程如下:
198+
199+
$$
200+
f[i][j] = \max(s[j + 1] - s[i + 1] - f[i + 1][j], s[j] - s[i] - f[i][j - 1])
201+
$$
202+
203+
在计算 $f[i][j]$ 时,我们需要保证 $f[i + 1][j]$ 和 $f[i][j - 1]$ 已经被计算出来,因此我们需要按照从大到小的顺序枚举 $i,ドル从小到大的顺序枚举 $j$。
204+
205+
最后,答案即为 $f[0][n - 1]$。
206+
207+
时间复杂度 $O(n^2),ドル空间复杂度 $O(n^2)$。其中 $n$ 为石子的数量。
208+
209+
<!-- tabs:start -->
210+
211+
```python
212+
class Solution:
213+
def stoneGameVII(self, stones: List[int]) -> int:
214+
s = list(accumulate(stones, initial=0))
215+
n = len(stones)
216+
f = [[0] * n for _ in range(n)]
217+
for i in range(n - 2, -1, -1):
218+
for j in range(i + 1, n):
219+
a = s[j + 1] - s[i + 1] - f[i + 1][j]
220+
b = s[j] - s[i] - f[i][j - 1]
221+
f[i][j] = max(a, b)
222+
return f[0][-1]
223+
```
224+
225+
```java
226+
class Solution {
227+
public int stoneGameVII(int[] stones) {
228+
int n = stones.length;
229+
int[] s = new int[n + 1];
230+
for (int i = 0; i < n; ++i) {
231+
s[i + 1] = s[i] + stones[i];
232+
}
233+
int[][] f = new int[n][n];
234+
for (int i = n - 2; i >= 0; --i) {
235+
for (int j = i + 1; j < n; ++j) {
236+
int a = s[j + 1] - s[i + 1] - f[i + 1][j];
237+
int b = s[j] - s[i] - f[i][j - 1];
238+
f[i][j] = Math.max(a, b);
239+
}
240+
}
241+
return f[0][n - 1];
242+
}
243+
}
244+
```
245+
246+
```cpp
247+
class Solution {
248+
public:
249+
int stoneGameVII(vector<int>& stones) {
250+
int n = stones.size();
251+
int s[n + 1];
252+
memset(s, 0, sizeof(s));
253+
for (int i = 0; i < n; ++i) {
254+
s[i + 1] = s[i] + stones[i];
255+
}
256+
int f[n][n];
257+
memset(f, 0, sizeof(f));
258+
for (int i = n - 2; i >= 0; --i) {
259+
for (int j = i + 1; j < n; ++j) {
260+
int a = s[j + 1] - s[i + 1] - f[i + 1][j];
261+
int b = s[j] - s[i] - f[i][j - 1];
262+
f[i][j] = max(a, b);
263+
}
264+
}
265+
return f[0][n - 1];
266+
}
267+
};
268+
```
269+
270+
```go
271+
func stoneGameVII(stones []int) int {
272+
n := len(stones)
273+
s := make([]int, n+1)
274+
for i, x := range stones {
275+
s[i+1] = s[i] + x
276+
}
277+
f := make([][]int, n)
278+
for i := range f {
279+
f[i] = make([]int, n)
280+
}
281+
for i := n - 2; i >= 0; i-- {
282+
for j := i + 1; j < n; j++ {
283+
f[i][j] = max(s[j+1]-s[i+1]-f[i+1][j], s[j]-s[i]-f[i][j-1])
284+
}
285+
}
286+
return f[0][n-1]
287+
}
288+
```
289+
290+
```ts
291+
function stoneGameVII(stones: number[]): number {
292+
const n = stones.length;
293+
const s: number[] = Array(n + 1).fill(0);
294+
for (let i = 0; i < n; ++i) {
295+
s[i + 1] = s[i] + stones[i];
296+
}
297+
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
298+
for (let i = n - 2; ~i; --i) {
299+
for (let j = i + 1; j < n; ++j) {
300+
f[i][j] = Math.max(s[j + 1] - s[i + 1] - f[i + 1][j], s[j] - s[i] - f[i][j - 1]);
301+
}
302+
}
303+
return f[0][n - 1];
304+
}
305+
```
306+
170307
<!-- end -->

‎solution/1600-1699/1690.Stone Game VII/README_EN.md‎

Lines changed: 140 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ The time complexity is $O(n^2),ドル and the space complexity is $O(n^2)$. Here, $n$
6565
class Solution:
6666
def stoneGameVII(self, stones: List[int]) -> int:
6767
@cache
68-
def dfs(i, j):
68+
def dfs(i: int, j: int) -> int:
6969
if i > j:
7070
return 0
7171
a = s[j + 1] - s[i + 1] - dfs(i + 1, j)
@@ -161,6 +161,145 @@ func stoneGameVII(stones []int) int {
161161
}
162162
```
163163

164+
```ts
165+
function stoneGameVII(stones: number[]): number {
166+
const n = stones.length;
167+
const s: number[] = Array(n + 1).fill(0);
168+
for (let i = 0; i < n; ++i) {
169+
s[i + 1] = s[i] + stones[i];
170+
}
171+
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
172+
const dfs = (i: number, j: number): number => {
173+
if (i > j) {
174+
return 0;
175+
}
176+
if (f[i][j]) {
177+
return f[i][j];
178+
}
179+
const a = s[j + 1] - s[i + 1] - dfs(i + 1, j);
180+
const b = s[j] - s[i] - dfs(i, j - 1);
181+
return (f[i][j] = Math.max(a, b));
182+
};
183+
return dfs(0, n - 1);
184+
}
185+
```
186+
187+
<!-- tabs:end -->
188+
189+
### Solution 2: Dynamic Programming
190+
191+
We can convert the memoization search in Solution 1 into dynamic programming. We define $f[i][j]$ as the score difference between the first and second players when the remaining stones are $stones[i], stones[i + 1], \dots, stones[j]$. Therefore, the answer is $f[0][n - 1]$.
192+
193+
The state transition equation is as follows:
194+
195+
$$
196+
f[i][j] = \max(s[j + 1] - s[i + 1] - f[i + 1][j], s[j] - s[i] - f[i][j - 1])
197+
$$
198+
199+
When calculating $f[i][j],ドル we need to ensure that $f[i + 1][j]$ and $f[i][j - 1]$ have been calculated. Therefore, we need to enumerate $i$ in descending order and $j$ in ascending order.
200+
201+
Finally, the answer is $f[0][n - 1]$.
202+
203+
The time complexity is $O(n^2),ドル and the space complexity is $O(n^2)$. Here, $n$ is the number of stones.
204+
205+
<!-- tabs:start -->
206+
207+
```python
208+
class Solution:
209+
def stoneGameVII(self, stones: List[int]) -> int:
210+
s = list(accumulate(stones, initial=0))
211+
n = len(stones)
212+
f = [[0] * n for _ in range(n)]
213+
for i in range(n - 2, -1, -1):
214+
for j in range(i + 1, n):
215+
a = s[j + 1] - s[i + 1] - f[i + 1][j]
216+
b = s[j] - s[i] - f[i][j - 1]
217+
f[i][j] = max(a, b)
218+
return f[0][-1]
219+
```
220+
221+
```java
222+
class Solution {
223+
public int stoneGameVII(int[] stones) {
224+
int n = stones.length;
225+
int[] s = new int[n + 1];
226+
for (int i = 0; i < n; ++i) {
227+
s[i + 1] = s[i] + stones[i];
228+
}
229+
int[][] f = new int[n][n];
230+
for (int i = n - 2; i >= 0; --i) {
231+
for (int j = i + 1; j < n; ++j) {
232+
int a = s[j + 1] - s[i + 1] - f[i + 1][j];
233+
int b = s[j] - s[i] - f[i][j - 1];
234+
f[i][j] = Math.max(a, b);
235+
}
236+
}
237+
return f[0][n - 1];
238+
}
239+
}
240+
```
241+
242+
```cpp
243+
class Solution {
244+
public:
245+
int stoneGameVII(vector<int>& stones) {
246+
int n = stones.size();
247+
int s[n + 1];
248+
memset(s, 0, sizeof(s));
249+
for (int i = 0; i < n; ++i) {
250+
s[i + 1] = s[i] + stones[i];
251+
}
252+
int f[n][n];
253+
memset(f, 0, sizeof(f));
254+
for (int i = n - 2; i >= 0; --i) {
255+
for (int j = i + 1; j < n; ++j) {
256+
int a = s[j + 1] - s[i + 1] - f[i + 1][j];
257+
int b = s[j] - s[i] - f[i][j - 1];
258+
f[i][j] = max(a, b);
259+
}
260+
}
261+
return f[0][n - 1];
262+
}
263+
};
264+
```
265+
266+
```go
267+
func stoneGameVII(stones []int) int {
268+
n := len(stones)
269+
s := make([]int, n+1)
270+
for i, x := range stones {
271+
s[i+1] = s[i] + x
272+
}
273+
f := make([][]int, n)
274+
for i := range f {
275+
f[i] = make([]int, n)
276+
}
277+
for i := n - 2; i >= 0; i-- {
278+
for j := i + 1; j < n; j++ {
279+
f[i][j] = max(s[j+1]-s[i+1]-f[i+1][j], s[j]-s[i]-f[i][j-1])
280+
}
281+
}
282+
return f[0][n-1]
283+
}
284+
```
285+
286+
```ts
287+
function stoneGameVII(stones: number[]): number {
288+
const n = stones.length;
289+
const s: number[] = Array(n + 1).fill(0);
290+
for (let i = 0; i < n; ++i) {
291+
s[i + 1] = s[i] + stones[i];
292+
}
293+
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
294+
for (let i = n - 2; ~i; --i) {
295+
for (let j = i + 1; j < n; ++j) {
296+
f[i][j] = Math.max(s[j + 1] - s[i + 1] - f[i + 1][j], s[j] - s[i] - f[i][j - 1]);
297+
}
298+
}
299+
return f[0][n - 1];
300+
}
301+
```
302+
164303
<!-- tabs:end -->
165304

166305
<!-- end -->

‎solution/1600-1699/1690.Stone Game VII/Solution.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
class Solution:
22
def stoneGameVII(self, stones: List[int]) -> int:
33
@cache
4-
def dfs(i, j):
4+
def dfs(i: int, j: int) ->int:
55
if i > j:
66
return 0
77
a = s[j + 1] - s[i + 1] - dfs(i + 1, j)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function stoneGameVII(stones: number[]): number {
2+
const n = stones.length;
3+
const s: number[] = Array(n + 1).fill(0);
4+
for (let i = 0; i < n; ++i) {
5+
s[i + 1] = s[i] + stones[i];
6+
}
7+
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
8+
const dfs = (i: number, j: number): number => {
9+
if (i > j) {
10+
return 0;
11+
}
12+
if (f[i][j]) {
13+
return f[i][j];
14+
}
15+
const a = s[j + 1] - s[i + 1] - dfs(i + 1, j);
16+
const b = s[j] - s[i] - dfs(i, j - 1);
17+
return (f[i][j] = Math.max(a, b));
18+
};
19+
return dfs(0, n - 1);
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public:
3+
int stoneGameVII(vector<int>& stones) {
4+
int n = stones.size();
5+
int s[n + 1];
6+
memset(s, 0, sizeof(s));
7+
for (int i = 0; i < n; ++i) {
8+
s[i + 1] = s[i] + stones[i];
9+
}
10+
int f[n][n];
11+
memset(f, 0, sizeof(f));
12+
for (int i = n - 2; i >= 0; --i) {
13+
for (int j = i + 1; j < n; ++j) {
14+
int a = s[j + 1] - s[i + 1] - f[i + 1][j];
15+
int b = s[j] - s[i] - f[i][j - 1];
16+
f[i][j] = max(a, b);
17+
}
18+
}
19+
return f[0][n - 1];
20+
}
21+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
func stoneGameVII(stones []int) int {
2+
n := len(stones)
3+
s := make([]int, n+1)
4+
for i, x := range stones {
5+
s[i+1] = s[i] + x
6+
}
7+
f := make([][]int, n)
8+
for i := range f {
9+
f[i] = make([]int, n)
10+
}
11+
for i := n - 2; i >= 0; i-- {
12+
for j := i + 1; j < n; j++ {
13+
f[i][j] = max(s[j+1]-s[i+1]-f[i+1][j], s[j]-s[i]-f[i][j-1])
14+
}
15+
}
16+
return f[0][n-1]
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Solution {
2+
public int stoneGameVII(int[] stones) {
3+
int n = stones.length;
4+
int[] s = new int[n + 1];
5+
for (int i = 0; i < n; ++i) {
6+
s[i + 1] = s[i] + stones[i];
7+
}
8+
int[][] f = new int[n][n];
9+
for (int i = n - 2; i >= 0; --i) {
10+
for (int j = i + 1; j < n; ++j) {
11+
int a = s[j + 1] - s[i + 1] - f[i + 1][j];
12+
int b = s[j] - s[i] - f[i][j - 1];
13+
f[i][j] = Math.max(a, b);
14+
}
15+
}
16+
return f[0][n - 1];
17+
}
18+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /