zoukankan      html  css  js  c++  java
  • hdu 6185 递推+【矩阵快速幂】

    <题目链接>

    <转载于 >>> >

    题目大意:

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

    解题分析:

    看到题目所给n的数据这么大,就知道肯定存在递推公式,至于递推公式的具体的分析过程  >>>大牛博客。求出递推公式后,由于数据太大,所以我们利用矩阵快速幂来加速。当然,如果比赛的时候想不到递推公式,我们也可以通过搜素得到前面的几组数据,然后在通过高斯消元来得到符合这些数据的公式的通解,最后再利用矩阵快速幂来求解。

    #include <iostream> 
    #include <cstring>
    #include <cstdio>
    using namespace std; 
    #define LL long long 
    const int mod=1000000007; 
    struct matrix
    {
        LL x[4][4];
    };
    matrix mutimatrix(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_powmatrix(matrix a,LL 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=mutimatrix(temp,a);
    
            a=mutimatrix(a,a);
            n>>=1;
        }
        return temp;
    } 
    
    
    int main()
    {
            LL n;
            while(scanf("%lld",&n)!=EOF)
            {
                //前面四个手算下
                if(n==1)
                {
                    printf("1
    ");
                    continue;
                }
                if(n==2)
                {
                    printf("5
    ");
                    continue;
                }
                if(n==3)
                {
                    printf("11
    ");
                    continue;
                }
                if(n==4)
                {
                    printf("36
    ");
                    continue;
                }
    
            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_powmatrix(st,n-4);//经过n-4次相乘
            st=mutimatrix(init,st);//然后再乘上初始矩阵
    
            printf("%lld
    ",(st.x[0][0]+mod)%mod);
        }
        return 0; 
    } 

    2018-08-09

  • 相关阅读:
    vm12序列号
    三星手机官方固件下载
    MSTP故障处理手册
    分享一个高清壁纸网站
    ThinkPad X220 完美黑苹果 Hackintosh OS X 10.11 El Capitan
    一句命令激活windows/office
    Win10+VMplayer12中U盘无法挂载解决
    记一次金士顿DT100 G3 32G修复
    飘雪代码2枚
    禁用安全模式
  • 原文地址:https://www.cnblogs.com/00isok/p/9452547.html
Copyright © 2011-2022 走看看