2015编程之美 骨牌覆盖问题·二 (快速幂)

来源:互联网 发布:java 7并发编程实战 编辑:程序博客网 时间:2024/06/05 12:08

描述

上一周我们研究了2xN的骨牌问题,这一周我们不妨加大一下难度,研究一下3xN的骨牌问题?
所以我们的题目是:对于3xN的棋盘,使用1x2的骨牌去覆盖一共有多少种不同的覆盖方法呢?
首先我们可以肯定,奇数长度一定是没有办法覆盖的;对于偶数长度,比如2,4,我们有下面几种覆盖方式:

提示:3xN骨牌覆盖

输入

第1行:1个整数N。表示棋盘长度。1≤N≤100,000,000

输出

第1行:1个整数,表示覆盖方案数 MOD 12357

样例输入
62247088
样例输出
4037

这个是网上别人做的,但是他的用时肯定比我们用快速幂大,其思想如下

其实仔细想想画一画也可以得到递推公式,假设奇数的方案数不为0,只要有一个方块达到奇数长度,就算是其中一个方案,那么有:a[0] = 0; a[1] = 2; a[2] = 3;

对于奇数:a[i] = 2*a[i-1] + a[i-2];  对于偶数:a[i] = 3*a[i-2] + a[i-3];

#include <iostream>
using namespace std;
const long long mod=12357;
long long N,A[5];
void solve()
{
    A[0]=0;A[1]=2;A[2]=3;
    for(long long i=3;i<=N;i++)
    {
        if(i&1)
            A[i%5]=(2*A[(i-1+5)%5]+A[(i-2+5)%5])%mod;
        else
            A[i%5]=(3*A[(i-2+5)%5]+A[(i-3+5)%5])%mod;
    }
    cout<<A[N%5]<<endl;
}
int main()
{
    while(cin>>N)
    {
        if(N&1)
            cout<<"0"<<endl;
        else
          solve();
    }
    return 0;
}

这是我用快速幂的代码
#include <iostream>
#include <string.h>using namespace std;const long long mod=12357;struct node{    long long m[8][8];};node mul(node A,node B){    node C;    memset(C.m,0,sizeof(C.m));    for(int i=0;i<8;i++)        for(int j=0;j<8;j++)          for(int k=0;k<8;k++)            C.m[i][j]+=((A.m[i][k]%mod)*(B.m[k][j]%mod))%mod;    return C;}node pow(node M,long long N){    node res;    memset(res.m,0,sizeof(res.m));    for(int i=0;i<8;i++)        res.m[i][i]=1;    while(N)    {        if(N&1)            res=mul(res,M);        M=mul(M,M);        N/=2;    }    return res;}int main(){    long long N;    while(cin>>N)    {        if(N&1)        {            cout<<"0"<<endl;            continue;        }        node A,M;        memset(A.m,0,sizeof(A.m));        memset(M.m,0,sizeof(M.m));        A.m[0][7]=1;        for(int i=0;i<8;i++)            M.m[i][7-i]=1;        M.m[3][7]=M.m[6][7]=M.m[7][3]=M.m[7][6]=1;        node ans;        memset(ans.m,0,sizeof(ans.m));        ans=pow(M,N);        ans=mul(A,ans);        cout<<ans.m[0][7]%mod<<endl;    }    return 0;}

0 0
原创粉丝点击