三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007
递归:s[i]=s[i-1]+s[i-2]+s[i-3]
s[i]是走到第i节台阶的方式
题目
int s[i]=(s[i-1]+s[i-2]+s[i-3])%M
结果错误,说明是三数相加时,超过了INT范围,自然为负的。
那如何解决呢?
long s[i]=(s[i-1]+s[i-2]+s[i-3])%M
- 进一步取模
s[i]=( (s[i-1]+s[i-2])%M+s[i-3] )%M
为啥过程中取余不会影响结果呢?
设s’为s取余后的结果。
s'=s%M
s'[i]=s[i]%M=s[i]-n*M
- 然后台阶又走了一层
s'[i+1]=s[i+1]%M=(s[i]+s[i-1]+s[i-2])%M=( (s[i]+s[i-1])%M + S[i-2]%M)%M=
( ((S[i]-n*M)+S[i-1]%M)%M +S[i-2]%M )%M=( (S[i]+S[i-1])%M +s[i-2]%M)%M=
((S[i]+S[i-1])%M +s[i-2]%M)%M=((S[i]+S[i-1])%M +s[i-2])%M
常见取余
(a + b) % p = (a % p + b % p) % p=(a%p+b)%p
设a=k1p+c
b=k2p+d
(a+b)%p=(k1p+c+k2p+d)%p=((k1p+c)%p+(k2p+d)%p)%p=(c%p+d%p)%p
(a%p+b)%p=(c%p+b)%p=(c%p%p+b%p)%p=(c%p+b%p)%p=(c%p+(k2p+d)%p)%p=(c%p+d%p)%p
(a - b) % p = (a % p - b % p) % p
(a * b) % p = (a % p * b % p) % p
a ^ b % p = ((a % p)^b) % p
结合律:
((a+b) % p + c) % p = (a + (b+c) % p) % p
((ab) % p * c)% p = (a * (bc) % p) % p
分配律:
(a+b) % p = ( a % p + b % p ) % p
((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p