An attendance record for a student can be represented as a string where each character signifies whether the student was absent, late, or present on that day. The record only contains the following three characters:
'A': Absent.
'L': Late.
'P': Present.
Any student is eligible for an attendance award if they meet both of the following criteria:
The student was absent ('A') for strictly fewer than 2 days total.
The student was never late ('L') for 3 or more consecutive days.
Given an integer n, return the number of possible attendance records of lengthn that make a student eligible for an attendance award. The answer may be very large, so return it modulo109 + 7.
Example 1:
Input: n = 2
Output: 8
Explanation: There are 8 records with length 2 that are eligible for an award:
"PP", "AP", "PA", "LP", "PL", "AL", "LA", "LL"
Only "AA" is not eligible because there are 2 absences (there need to be fewer than 2).
Example 2:
Input: n = 1
Output: 3
Example 3:
Input: n = 10101
Output: 183236316
Constraints:
1 <= n <= 105
Solutions
Solution 1: Dynamic Programming
Thinking
A valid length-\(n\) record limits absences and consecutive lates. Enumerating \(3^n\) strings is impossible for \(n\) up to \(10^5\).
Six numbers are enough: absences used (\(0\) or \(1\)) and the current late streak (\(0\), \(1\), or \(2\)). A top-down search still chains \(n\) calls and overflows the stack on the largest \(n\).
So we walk the days backward. \(f(j,k)\) is the number of ways to finish the remaining days with \(j\) absences already used and late streak \(k\). After the last day that value is \(1\). One day earlier, place P (streak returns to \(0\)), an A when \(j=0\), or an L when \(k<2\). The answer is \(f(0,0)\) modulo \(10^9+7\).
Let \(f(j,k)\) be the number of ways to fill every remaining day when \(j\) absences are already used and the current late streak is \(k\). With no days left, \(f(j,k)=1\). The answer is \(f(0,0)\) after \(n\) backward steps.
Each step replaces the table by the three choices:
present, which resets the streak: \(f(j,0)\);
absent, only when \(j=0\): \(f(1,0)\);
late, only when \(k<2\): \(f(j,k+1)\).
Write the new values into a fresh table so the previous day is not overwritten. Take every sum modulo \(10^9+7\).
The time complexity is \(O(n)\) and the space complexity is \(O(1)\).
The previous method keeps only the six suffix counts. This one records every prefix so the day index stays explicit.
\(dp[i][j][k]\) is the number of ways for the first \(i+1\) days with \(j\) absences and a late streak of \(k\). Transitions place A, L, or P from day \(i-1\). Sum every \((j,k)\) on the last day.