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 1403957

Browse files
feat: add solutions to lc problem: No.3320 (doocs#3640)
No.3320.Count The Number of Winning Sequences
1 parent 5d8c2f9 commit 1403957

File tree

6 files changed

+539
-10
lines changed

6 files changed

+539
-10
lines changed

‎solution/3300-3399/3320.Count The Number of Winning Sequences/README.md‎

Lines changed: 184 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,32 +79,211 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3320.Co
7979

8080
<!-- solution:start -->
8181

82-
### 方法一
82+
### 方法一:记忆化搜索
83+
84+
我们设计一个函数 $\textit{dfs}(i, j, k),ドル其中 $i$ 表示从字符串 $s$ 的第 $i$ 个字符开始,目前 $\textit{Alice}$ 与 $\textit{Bob}$ 的分数差为 $j,ドル并且 $\textit{Bob}$ 上一次召唤的生物是 $k,ドル一共有多少种 $\textit{Bob}$ 的出招序列可以战胜 $\textit{Alice}$。
85+
86+
那么答案就是 $\textit{dfs}(0, 0, -1)$。其中 $-1$ 表示 $\textit{Bob}$ 还没有召唤过生物。在除了 $\textit{Python}$ 之外的语言中,由于分数差可能为负数,我们可以将分数差加上 $n,ドル这样就可以保证分数差为非负数。
87+
88+
函数 $\textit{dfs}(i, j, k)$ 的计算过程如下:
89+
90+
- 如果 $n - i \leq j,ドル那么剩余的回合数不足以使 $\textit{Bob}$ 的分数超过 $\textit{Alice}$ 的分数,此时返回 0ドル$。
91+
- 如果 $i \geq n,ドル那么所有回合已经结束,如果 $\textit{Bob}$ 的分数小于 0ドル,ドル那么返回 1ドル,ドル否则返回 0ドル$。
92+
- 否则,我们枚举 $\textit{Bob}$ 这一回合召唤的生物,如果这一回合召唤的生物与上一回合召唤的生物相同,那么这一回合 $\textit{Bob}$ 无法获胜,直接跳过。否则,我们递归计算 $\textit{dfs}(i + 1, j + \textit{calc}(d[s[i]], l), l),ドル其中 $\textit{calc}(x, y)$ 表示 $x$ 与 $y$ 之间的胜负关系,而 $d$ 是一个映射,将字符映射到 $\textit{012}$。我们将所有的结果相加并对 10ドル^9 + 7$ 取模。
93+
94+
时间复杂度 $O(n^2 \times k^2),ドル其中 $n$ 是字符串 $s$ 的长度,而 $k$ 表示字符集的大小。空间复杂度 $O(n^2 \times k)$。
8395

8496
<!-- tabs:start -->
8597

8698
#### Python3
8799

88100
```python
89-
101+
class Solution:
102+
def countWinningSequences(self, s: str) -> int:
103+
def calc(x: int, y: int) -> int:
104+
if x == y:
105+
return 0
106+
if x < y:
107+
return 1 if x == 0 and y == 2 else -1
108+
return -1 if x == 2 and y == 0 else 1
109+
110+
@cache
111+
def dfs(i: int, j: int, k: int) -> int:
112+
if len(s) - i <= j:
113+
return 0
114+
if i >= len(s):
115+
return int(j < 0)
116+
res = 0
117+
for l in range(3):
118+
if l == k:
119+
continue
120+
res = (res + dfs(i + 1, j + calc(d[s[i]], l), l)) % mod
121+
return res
122+
123+
mod = 10**9 + 7
124+
d = {"F": 0, "W": 1, "E": 2}
125+
ans = dfs(0, 0, -1)
126+
dfs.cache_clear()
127+
return ans
90128
```
91129

92130
#### Java
93131

94132
```java
95-
133+
class Solution {
134+
private int n;
135+
private char[] s;
136+
private int[] d = new int[26];
137+
private Integer[][][] f;
138+
private final int mod = (int) 1e9 + 7;
139+
140+
public int countWinningSequences(String s) {
141+
d['W' - 'A'] = 1;
142+
d['E' - 'A'] = 2;
143+
this.s = s.toCharArray();
144+
n = this.s.length;
145+
f = new Integer[n][n + n + 1][4];
146+
return dfs(0, n, 3);
147+
}
148+
149+
private int dfs(int i, int j, int k) {
150+
if (n - i <= j - n) {
151+
return 0;
152+
}
153+
if (i >= n) {
154+
return j - n < 0 ? 1 : 0;
155+
}
156+
if (f[i][j][k] != null) {
157+
return f[i][j][k];
158+
}
159+
160+
int ans = 0;
161+
for (int l = 0; l < 3; ++l) {
162+
if (l == k) {
163+
continue;
164+
}
165+
ans = (ans + dfs(i + 1, j + calc(d[s[i] - 'A'], l), l)) % mod;
166+
}
167+
return f[i][j][k] = ans;
168+
}
169+
170+
private int calc(int x, int y) {
171+
if (x == y) {
172+
return 0;
173+
}
174+
if (x < y) {
175+
return x == 0 && y == 2 ? 1 : -1;
176+
}
177+
return x == 2 && y == 0 ? -1 : 1;
178+
}
179+
}
96180
```
97181

98182
#### C++
99183

100184
```cpp
101-
185+
class Solution {
186+
public:
187+
int countWinningSequences(string s) {
188+
int n = s.size();
189+
int d[26]{};
190+
d['W' - 'A'] = 1;
191+
d['E' - 'A'] = 2;
192+
int f[n][n + n + 1][4];
193+
memset(f, -1, sizeof(f));
194+
auto calc = [](int x, int y) -> int {
195+
if (x == y) {
196+
return 0;
197+
}
198+
if (x < y) {
199+
return x == 0 && y == 2 ? 1 : -1;
200+
}
201+
return x == 2 && y == 0 ? -1 : 1;
202+
};
203+
const int mod = 1e9 + 7;
204+
auto dfs = [&](auto&& dfs, int i, int j, int k) -> int {
205+
if (n - i <= j - n) {
206+
return 0;
207+
}
208+
if (i >= n) {
209+
return j - n < 0 ? 1 : 0;
210+
}
211+
if (f[i][j][k] != -1) {
212+
return f[i][j][k];
213+
}
214+
int ans = 0;
215+
for (int l = 0; l < 3; ++l) {
216+
if (l == k) {
217+
continue;
218+
}
219+
ans = (ans + dfs(dfs, i + 1, j + calc(d[s[i] - 'A'], l), l)) % mod;
220+
}
221+
return f[i][j][k] = ans;
222+
};
223+
return dfs(dfs, 0, n, 3);
224+
}
225+
};
102226
```
103227
104228
#### Go
105229
106230
```go
107-
231+
func countWinningSequences(s string) int {
232+
const mod int = 1e9 + 7
233+
d := [26]int{}
234+
d['W'-'A'] = 1
235+
d['E'-'A'] = 2
236+
n := len(s)
237+
f := make([][][4]int, n)
238+
for i := range f {
239+
f[i] = make([][4]int, n+n+1)
240+
for j := range f[i] {
241+
for k := range f[i][j] {
242+
f[i][j][k] = -1
243+
}
244+
}
245+
}
246+
calc := func(x, y int) int {
247+
if x == y {
248+
return 0
249+
}
250+
if x < y {
251+
if x == 0 && y == 2 {
252+
return 1
253+
}
254+
return -1
255+
}
256+
if x == 2 && y == 0 {
257+
return -1
258+
}
259+
return 1
260+
}
261+
var dfs func(int, int, int) int
262+
dfs = func(i, j, k int) int {
263+
if n-i <= j-n {
264+
return 0
265+
}
266+
if i >= n {
267+
if j-n < 0 {
268+
return 1
269+
}
270+
return 0
271+
}
272+
if v := f[i][j][k]; v != -1 {
273+
return v
274+
}
275+
ans := 0
276+
for l := 0; l < 3; l++ {
277+
if l == k {
278+
continue
279+
}
280+
ans = (ans + dfs(i+1, j+calc(d[s[i]-'A'], l), l)) % mod
281+
}
282+
f[i][j][k] = ans
283+
return ans
284+
}
285+
return dfs(0, n, 3)
286+
}
108287
```
109288

110289
<!-- tabs:end -->

0 commit comments

Comments
(0)

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