1. 程式人生 > >HDU6185 Covering (遞推+矩陣快速冪)

HDU6185 Covering (遞推+矩陣快速冪)

esp over () n-1 告訴 matrix \n nbsp 答案

大致題意:讓你用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; }

HDU6185 Covering (遞推+矩陣快速冪)