HDU6185 Covering (递推+矩阵快速幂)

大致题意:让你用1*2规格的地毯去铺4*n规格的地面,告诉你n,问有多少种不同的方案使得地面恰好被铺满且地毯不重叠。答案对1000000007取模

递推得f(n)=f(n-1)+5*f(n-2)+f(n-3)-f(n-4),因为n很大,所以接下来用矩阵快速幂搞搞就可以了。 

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

long long n;
long long mod=1000000007;

struct matrix
{
    long long x[4][4];
};

matrix muti(matrix a,matrix b)
{
    matrix temp;
    memset(temp.x,0,sizeof(temp.x));
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            for(int k=0;k<4;k++)
            {
                temp.x[i][j]+=a.x[i][k]*b.x[k][j];
                temp.x[i][j]%=mod;
            }
        }
    }
    return temp;
}

matrix k_pow(matrix a,long long n)
{
    matrix temp;
    memset(temp.x,0,sizeof(temp.x));
    for(int i=0;i<4;i++)
    {
        temp.x[i][i]=1;
    }
    while(n)
    {
        if(n&1)
        {
            temp=muti(temp,a);
        }
        a=muti(a,a);
        n>>=1;

    }
    return temp;

}

int main()
{
    while(~scanf("%lld",&n))
    {
        if(n==1) printf("1\n");
        else if(n==2) printf("5\n");
        else if(n==3) printf("11\n");
        else if(n==4) printf("36\n");
        else if(n>4)
        {
            matrix st;
            memset(st.x,0,sizeof(st.x));
            st.x[0][0]=1;
            st.x[1][0]=5;
            st.x[2][0]=1;
            st.x[3][0]=-1;

            st.x[0][1]=1;
            st.x[1][2]=1;
            st.x[2][3]=1;

            matrix init;
            memset(init.x,0,sizeof(init.x));

            init.x[0][0]=36;
            init.x[0][1]=11;
            init.x[0][2]=5;
            init.x[0][3]=1;

            st=k_pow(st,n-4);
            st=muti(init,st);


            printf("%lld\n",(st.x[0][0]+mod)%mod);

        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Fy1999/p/9093860.html