Sam 数(矩阵乘法)

Sam 数

Sam 数是指相邻的两位数字相差不超过 2 的数。求长度为 n 的 Sam 数有多少个。输出对 1000000007 取余后的结果。 n <= 10^18 。

分析 :这个数据范围很吓人,所以必须要 O(logn) 的算法。

首先,递推式很明显:

用 f(i, j) 表示第 j 位为 i 时总的个数(先不考虑各种特殊情况),则

f(i, j) = f(i-2, j-1) + f(i-1, j-1) + f(i, j-1) + f(i+1, j-1) + f(i+2, j-1)

我们考虑这样一个矩阵 A :

[ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]

这个 1*10 矩阵表示当第一位为 i 且一共只有 1 位时的方案数。

考虑另一个矩阵 B :


这个矩阵的第 i 行 第 j 列 表示当某一位为 j ,相邻一位取 i 时的方案数。

我们将矩阵 A 与 B 相乘一次,可以得到一个 1*10 的矩阵,很明显,这个矩阵的第 i个元素的值表示当第一位为 i 且一共有 2 位时的方案数,那么矩阵的元素和即 n=2 时的结果。

同理,将 A 不断地与 B 相乘,对于 n ,最终得到的矩阵为 A * (B ^ n-1) 的结果,这个矩阵的元素和即最终答案。注意 n=1 的时候特判,这时 0 也算一个方案,所以答案为 10 。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值