【Leetcode】552
前言
题目链接
跟昨天相似的题目背景,但是题目是完全不一样的题目
昨天是一个简单的判断题目,今天是一个DP。
思路
当看到这个结果对***取余的时候基本就意味着不能枚举或者考虑出具体的每种情况
这个题目依然,dfs(a,l,n)表示当前存在A的个数a,当前连续的L为l,当前组成的长度,那么结果就是dfs(0,0,0)
具体而言,这个时候可以分为a=0和a=1两种情况
\(dfs(0,0,n)=dfs(0,0,n-1)+dfs(0,1,n-1)+dfs(0,2,n-1)\)
即表示当前长度为n,不存在A,末尾不存在连续的L可由上一天不是A且末尾存在可行即0~2个L的情况下最后一天写上P
同理
\(dfs(0,1,n)=dfs(0,0,n-1)\),\(dfs(0,2,n)=dfs(0,1,n-1)\)
\(dfs(1,0,n)=dfs(0,0,n-1)+dfs(0,1,n-1)+dfs(0,2,n-1)+dfs(1,0,n-1)+dfs(1,1,n-1)+dfs(1,2,n-1)\)
\(dfs(1,1,n)=dfs(1,0,n-1)\)
\(dfs(1,2,n)=dfs(1,1,n-1)\)
入口为 dfs(0,0,0)=1,而$a\neq 0 \text{ and }l\neq 0 $时候,dfs(a,l,0)=0
最后求解的是dfs(a,l,n),a=0,1,l=0,1,2
class Solution:
def checkRecord(self, n: int) -> int:
MOD = 10**9 + 7
@cache
def dfs(a,l,n):
if n==0:
return a==0 and l==0
if a==0:
if l==0:
return (dfs(0,0,n-1) + dfs(0,1,n-1) + dfs(0,2,n-1))%MOD
if l==1:
return dfs(0,0,n-1)
else:
return dfs(0,1,n-1)
else:
if l==0:
return (dfs(0,0,n-1)+dfs(0,1,n-1)+dfs(0,2,n-1)+dfs(1,0,n-1)+dfs(1,1,n-1)+dfs(1,2,n-1))%MOD
if l==1:
return dfs(1,0,n-1)
else:
return dfs(1,1,n-1)
return sum(dfs(a,l,n) for a in range(2) for l in range(3))
但是如果这么写的话,当n比较大的时候,就是递归深度很大,而爆内存
改写为递推的形式就可以了,而且代码更加清晰
class Solution:
def checkRecord(self, n: int) -> int:
MOD = 10**9 + 7
# 0 0A,0L
# 1 0A,1L
# 2 0A,2L
# 3 1A,0L
# 4 1A,1L
# 5 1A,2L
# dp = [0]*6
# dp[0] = 1
a,b,c,d,e,f = 1,0,0,0,0,0
for _ in range(n):
# dp = [dp[0]+dp[1]+dp[2],dp[0],dp[1],sum(dp),dp[3],dp[4]]
a, b, c, d, e, f = (a+b+c)%MOD,a,b,(a+b+c+d+e+f)%MOD,d,e
# return sum(dp)%MOD
return (a+b+c+d+e+f)%MOD
注意在更新dp的过程中对MOD的取模,如果过程保留大数,那么计算的时间就会很久导致超时。

浙公网安备 33010602011771号