Covering HDU - 6185

2018TYUT暑期ACM模拟赛(1)
Covering HDU - 6185
题意:用1*2的地毯铺满4*n的地方。
思路:找递推式,然后emmmm,看了大佬的题解。找递推式+矩阵快速幂,顺便学到矩阵快速幂,正好上学期上了数值计算,矩阵上的操作挺上手。这个参考的大佬的博客的思路是分类五类情况。然后一点点铺满。详细推导内容请点下方链接内容。个人感觉很符合我的脑回路,不知道下次写类似的能不能搞出来。

Covering HDU - 6185_第1张图片

//矩阵快速幂
#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod=1000000007;
struct matrix{
    ll x[4][4];
};
matrix multi(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 quick_multi(matrix a,ll n)//矩阵快速幂
{
    matrix temp=a;
    n--;
    /*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=multi(temp,a);
        a=multi(a,a);
        n>>=1;
    }
    return temp;
}
int main()
{
    ll n;
    while(cin>>n)
    {
        if(n==1)
        {
            printf("1\n");
            continue;
        }
        if(n==2)
        {
            printf("5\n");
            continue;
        }
        if(n==3)
        {
            printf("11\n");
            continue;
        }
        if(n==4)
        {
            printf("36\n");
            continue;
        }

        matrix A;
        matrix ans;
        memset(A.x,0,sizeof(A.x));
        memset(ans.x,0,sizeof(ans.x));
        A.x[0][0]=1;A.x[1][0]=5;A.x[2][0]=1;A.x[3][0]=-1;
        A.x[0][1]=1;A.x[1][2]=1;A.x[2][3]=1;
        ans.x[0][0]=36,ans.x[0][1]=11,ans.x[0][2]=5,ans.x[0][3]=1;
        A=quick_multi(A,n-4);
        ans=multi(ans,A);
        printf("%lld\n",(ans.x[0][0]+mod)%mod);
    }

    return 0;
}

参考博客

你可能感兴趣的:(contest,2018ACM模拟赛集训)