版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/88750708
从第一个格子跳到第 个格子,每次至少跳 格,求方案数
或者
把
个无色格子排成一行,可以把某些格子染成黑色,但两个黑色格子之间必须至少有
个无色格子,求方案数
首先第
个格子显然可以从第
然后方案数显然是
(因为可以跳出去)
然后就愉快
从染色的角度考虑,对于每个格子,不染色时方案书显然为 ,染色的话则加上 ,就得到了方程
这样就愉快
了
但是酱紫距离满分还是有很大差距滴
想到了啥?,矩阵乘法!
愉快 AC
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const LL WYC=1e9+7;
LL n;int m;
struct matrix
{
LL a[18][18];
}x,ans;
matrix operator *(matrix a,matrix b)
{
matrix c;
memset(&c,0,sizeof(c));
for(register int i=0;i<=m;i++)
for(register int j=0;j<=m;j++)
for(register int k=0;k<=m;k++)
(c.a[i][j]+=a.a[i][k]*b.a[k][j])%=WYC;
return c;
}
signed main()
{
scanf("%lld%d",&n,&m);n--;
x.a[m][m]=x.a[0][m]=1;
for(register int i=0;i<=m;i++) ans.a[0][i]=i+2,x.a[i+1][i]=1;
//初始化,前面m个格子的方案数显然为i+1,由于坐标从0开始所以是i+2
//然后只有f[i]=f[i-1]+f[i-m-1]的,其它的f[i-k]=f[i-k]
for(;n;n>>=1,x=x*x)
if(n&1) ans=ans*x;
printf("%lld",ans.a[0][0]);
}