您的位置:首页 > 其它

xdoj-1111

2016-11-09 17:52 274 查看
对于一排n个正方形,有f(n)种方案达成目标,若第n个块是白色,则有f(n-1)种方案,若第n个块是黑色,则第n-1个块必为白色,那么有f(n-2)+n-2种方案。

则f(n)=f(n-1)+f(n-2)+n-2 。

写成矩阵形式:

(https://img-blog.csdn.net/20161011211956406)

例如:(i,j)表示i个空涂j个的种类数

(9,2)=(7,1)+(6,1)+(5,1)+(4,1)+(3,1)+(2,1)+(1,1)

(9,3)=(7,2)+(6,2)+(5,2)+(4,2)+(3,2)

(9,4)=(7,3)+(6,3)+(5,3)

(9,5)=(7,4)

(8,2)=(6,1)+(5,1)+(4,1)+(3,1)+(2,1)+(1,1)

(8,3)=(6,2)+(5,2)+(4,2)+(3,2)

(8,4)=(6,3)+(5,3)

#include<cstdio>
#include<cstring>
typedef long long ll;
const ll mod=1e9+7;
struct Mat
{
ll mat[4][4];
};
Mat Mult(Mat a,Mat b)
{
Mat c;
memset(c.mat,0,sizeof(c.mat));
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
return c;
}

Mat QMult(Mat a,ll b)
{
Mat c;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
c.mat[i][j]=i==j;
while(b){
if(b&1)
c=Mult(c,a);
a=Mult(a,a);
b>>=1;
}
return c;
}

int main()
{
ll n;
while(~scanf("%lld",&n))
{
Mat res;
if(n==2)
{
puts("0");
continue;
}
else if(n==3)
{
puts("1");
continue;
}
memset(res.mat,0,sizeof(res.mat));
res.mat[0][0]=res.mat[0][1]=res.mat[0][2]=res.mat[1][0]=1;
res.mat[2][2]=res.mat[2][3]=res.mat[3][3]=1;
res=QMult(res,n-3);
printf("%lld\n",(res.mat[0][0]+2*res.mat[0][2]+res.mat[0][3])%mod);
6c29

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: