comments | difficulty | edit_url | rating | source | tags | ||
---|---|---|---|---|---|---|---|
true |
困难 |
2153 |
第 419 场周赛 Q3 |
|
Alice 和 Bob 正在玩一个幻想战斗游戏,游戏共有 n
回合,每回合双方各自都会召唤一个魔法生物:火龙(F
)、水蛇(W
)或地精(E
)。每回合中,双方 同时 召唤魔法生物,并根据以下规则得分:
- 如果一方召唤火龙而另一方召唤地精,召唤 火龙 的玩家将获得一分。
- 如果一方召唤水蛇而另一方召唤火龙,召唤 水蛇 的玩家将获得一分。
- 如果一方召唤地精而另一方召唤水蛇,召唤 地精 的玩家将获得一分。
- 如果双方召唤相同的生物,那么两个玩家都不会获得分数。
给你一个字符串 s
,包含 n
个字符 'F'
、'W'
和 'E'
,代表 Alice 每回合召唤的生物序列:
- 如果
s[i] == 'F'
,Alice 召唤火龙。 - 如果
s[i] == 'W'
,Alice 召唤水蛇。 - 如果
s[i] == 'E'
,Alice 召唤地精。
Bob 的出招序列未知,但保证 Bob 不会在连续两个回合中召唤相同的生物。如果在 n
轮后 Bob 获得的总分 严格大于 Alice 的总分,则 Bob 战胜 Alice。
返回 Bob 可以用来战胜 Alice 的不同出招序列的数量。
由于答案可能非常大,请返回答案对 109 + 7
取余 后的结果。
示例 1:
输入: s = "FFF"
输出: 3
解释:
Bob 可以通过以下 3 种出招序列战胜 Alice:"WFW"
、"FWF"
或 "WEW"
。注意,其他如 "WWE"
或 "EWW"
的出招序列是无效的,因为 Bob 不能在连续两个回合中使用相同的生物。
示例 2:
输入: s = "FWEFW"
输出: 18
解释:
Bob 可以通过以下出招序列战胜 Alice:"FWFWF"
、"FWFWE"
、"FWEFE"
、"FWEWE"
、"FEFWF"
、"FEFWE"
、"FEFEW"
、"FEWFE"
、"WFEFE"
、"WFEWE"
、"WEFWF"
、"WEFWE"
、"WEFEF"
、"WEFEW"
、"WEWFW"
、"WEWFE"
、"EWFWE"
或 "EWEWE"
。
提示:
1 <= s.length <= 1000
s[i]
是'F'
、'W'
或'E'
中的一个。
我们设计一个函数
那么答案就是
函数
- 如果
$n - i \leq j$ ,那么剩余的回合数不足以使$\textit{Bob}$ 的分数超过$\textit{Alice}$ 的分数,此时返回$0$ 。 - 如果
$i \geq n$ ,那么所有回合已经结束,如果$\textit{Bob}$ 的分数小于$0$ ,那么返回$1$ ,否则返回$0$ 。 - 否则,我们枚举
$\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$ 取模。
时间复杂度
class Solution:
def countWinningSequences(self, s: str) -> int:
def calc(x: int, y: int) -> int:
if x == y:
return 0
if x < y:
return 1 if x == 0 and y == 2 else -1
return -1 if x == 2 and y == 0 else 1
@cache
def dfs(i: int, j: int, k: int) -> int:
if len(s) - i <= j:
return 0
if i >= len(s):
return int(j < 0)
res = 0
for l in range(3):
if l == k:
continue
res = (res + dfs(i + 1, j + calc(d[s[i]], l), l)) % mod
return res
mod = 10**9 + 7
d = {"F": 0, "W": 1, "E": 2}
ans = dfs(0, 0, -1)
dfs.cache_clear()
return ans
class Solution {
private int n;
private char[] s;
private int[] d = new int[26];
private Integer[][][] f;
private final int mod = (int) 1e9 + 7;
public int countWinningSequences(String s) {
d['W' - 'A'] = 1;
d['E' - 'A'] = 2;
this.s = s.toCharArray();
n = this.s.length;
f = new Integer[n][n + n + 1][4];
return dfs(0, n, 3);
}
private int dfs(int i, int j, int k) {
if (n - i <= j - n) {
return 0;
}
if (i >= n) {
return j - n < 0 ? 1 : 0;
}
if (f[i][j][k] != null) {
return f[i][j][k];
}
int ans = 0;
for (int l = 0; l < 3; ++l) {
if (l == k) {
continue;
}
ans = (ans + dfs(i + 1, j + calc(d[s[i] - 'A'], l), l)) % mod;
}
return f[i][j][k] = ans;
}
private int calc(int x, int y) {
if (x == y) {
return 0;
}
if (x < y) {
return x == 0 && y == 2 ? 1 : -1;
}
return x == 2 && y == 0 ? -1 : 1;
}
}
class Solution {
public:
int countWinningSequences(string s) {
int n = s.size();
int d[26]{};
d['W' - 'A'] = 1;
d['E' - 'A'] = 2;
int f[n][n + n + 1][4];
memset(f, -1, sizeof(f));
auto calc = [](int x, int y) -> int {
if (x == y) {
return 0;
}
if (x < y) {
return x == 0 && y == 2 ? 1 : -1;
}
return x == 2 && y == 0 ? -1 : 1;
};
const int mod = 1e9 + 7;
auto dfs = [&](this auto&& dfs, int i, int j, int k) -> int {
if (n - i <= j - n) {
return 0;
}
if (i >= n) {
return j - n < 0 ? 1 : 0;
}
if (f[i][j][k] != -1) {
return f[i][j][k];
}
int ans = 0;
for (int l = 0; l < 3; ++l) {
if (l == k) {
continue;
}
ans = (ans + dfs(i + 1, j + calc(d[s[i] - 'A'], l), l)) % mod;
}
return f[i][j][k] = ans;
};
return dfs(0, n, 3);
}
};
func countWinningSequences(s string) int {
const mod int = 1e9 + 7
d := [26]int{}
d['W'-'A'] = 1
d['E'-'A'] = 2
n := len(s)
f := make([][][4]int, n)
for i := range f {
f[i] = make([][4]int, n+n+1)
for j := range f[i] {
for k := range f[i][j] {
f[i][j][k] = -1
}
}
}
calc := func(x, y int) int {
if x == y {
return 0
}
if x < y {
if x == 0 && y == 2 {
return 1
}
return -1
}
if x == 2 && y == 0 {
return -1
}
return 1
}
var dfs func(int, int, int) int
dfs = func(i, j, k int) int {
if n-i <= j-n {
return 0
}
if i >= n {
if j-n < 0 {
return 1
}
return 0
}
if v := f[i][j][k]; v != -1 {
return v
}
ans := 0
for l := 0; l < 3; l++ {
if l == k {
continue
}
ans = (ans + dfs(i+1, j+calc(d[s[i]-'A'], l), l)) % mod
}
f[i][j][k] = ans
return ans
}
return dfs(0, n, 3)
}