可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符:
'A'
:Absent,缺勤'L'
:Late,迟到'P'
:Present,到场
如果学生能够 同时 满足下面两个条件,则可以获得出勤奖励:
- 按 总出勤 计,学生缺勤(
'A'
)严格 少于两天。 - 学生 不会 存在 连续 3 天或 连续 3 天以上的迟到(
'L'
)记录。
给你一个整数 n
,表示出勤记录的长度(次数)。请你返回记录长度为 n
时,可能获得出勤奖励的记录情况 数量 。答案可能很大,所以返回对 109 + 7
取余 的结果。
示例 1:
输入:n = 2 输出:8 解释: 有 8 种长度为 2 的记录将被视为可奖励: "PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL" 只有"AA"不会被视为可奖励,因为缺勤次数为 2 次(需要少于 2 次)。
示例 2:
输入:n = 1 输出:3
示例 3:
输入:n = 10101 输出:183236316
提示:
1 <= n <= 105
问题简要描述:返回获得出勤奖励的记录情况数量
细节阐述:
- 函数 dfs(i,j,k),表示从第 i 个出勤记录开始,当前缺勤次数为 j,目前最后连续迟到次数为 k 时,可获得出勤奖励的情况数量
Java
class Solution {
int n;
Integer[][][] f;
final int MOD = (int) (1e9 + 7);
public int checkRecord(int n) {
this.n = n;
this.f = new Integer[n][2][3];
return dfs(0, 0, 0);
}
int dfs(int i, int j, int k) {
if (i >= n) {
return 1;
}
if (f[i][j][k] != null) {
return f[i][j][k];
}
int ans = dfs(i + 1, j, 0);
if (j == 0) {
ans = (ans + dfs(i + 1, j + 1, 0)) % MOD;
}
if (k < 2) {
ans = (ans + dfs(i + 1, j, k + 1)) % MOD;
}
return f[i][j][k] = ans;
}
}
Python3
class Solution:
def checkRecord(self, n: int) -> int:
@cache
def dfs(i: int, j: int, k: int) -> int:
if i >= n:
return 1
ans = dfs(i + 1, j, 0)
if j == 0:
ans += dfs(i + 1, j + 1, 0)
if k < 2:
ans += dfs(i + 1, j, k + 1)
return ans % mod
mod = 10 ** 9 + 7
ans = dfs(0, 0, 0) % mod
dfs.cache_clear()
return ans
C++
class Solution {
public:
int checkRecord(int n) {
int f[n][2][3];
memset(f, -1, sizeof(f));
const int mod = 1e9 + 7;
auto dfs = [&](auto&& dfs, int i, int j, int k)->int {
if (i >= n) {
return 1;
}
if (f[i][j][k] != -1) {
return f[i][j][k];
}
int ans = dfs(dfs, i + 1, j, 0);
if (j == 0) {
ans = (ans + dfs(dfs, i + 1, j + 1, 0)) % mod;
}
if (k < 2) {
ans = (ans + dfs(dfs, i + 1, j, k + 1)) % mod;
}
return f[i][j][k] = ans;
};
return dfs(dfs, 0, 0, 0);
}
};
Go
func checkRecord(n int) int {
f := make([][][]int, n)
for i := range f {
f[i] = make([][]int, 2)
for j := range f[i] {
f[i][j] = make([]int, 3)
for k := range f[i][j] {
f[i][j][k] = -1
}
}
}
const mod = 1e9 + 7
var dfs func(i, j, k int) int
dfs = func(i, j, k int) int {
if i >= n {
return 1
}
if f[i][j][k] != -1 {
return f[i][j][k]
}
ans := dfs(i+1, j, 0)
if j == 0 {
ans = (ans + dfs(i+1, j+1, 0)) % mod
}
if k < 2 {
ans = (ans + dfs(i+1, j, k+1)) % mod
}
f[i][j][k] = ans
return ans
}
return dfs(0, 0, 0)
}