1. 程式人生 > >Covering HDU

Covering HDU

題目
題意 4*n的方格塊 要用1*2和2*1的矩形填滿,問填發。

解題思路 : n最大為1e18,。 考慮矩陣快速冪。
先用狀壓DP打出前面幾項,然後for迴圈一個一個試求出遞推式係數。。。。。(高階技巧)
先考慮係數只有3向,然後一個一個往上加 直到只有唯一解。
這裡寫圖片描述
然後就是一個簡單的矩陣快速冪。

#include <string>
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; const int matX = 10; const int mod = 1e9 + 7; typedef long long LL; struct Matrix { long long n, m, s[matX][matX]; Matrix(int n, int m): n(n), m(n) { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) s[i][j] = 0; } } Matrix operator
*(const Matrix &P)const { Matrix ret(n, P.m); for(int i = 0; i < n; i++) { for(int k = 0; k < m; k++) { if(s[i][k]) { for(int j = 0; j < P.m; j++) { ret.s[i][j] = ((LL)s[i][k] * P.s[k][j] + ret.s[i][j]) % mod; } } } } return
ret; } Matrix operator^(const LL P)const { LL num = P; Matrix ret(n, m), tmp = *this; for(int i = 0; i < n; i++) ret.s[i][i] = 1; while(num) { if(num & 1) ret = ret * tmp; tmp = tmp * tmp; num >>= 1; } return ret; } }; int main(){ Matrix E(5,5); E.s[0][0]=1,E.s[0][1]=5,E.s[0][2]=1,E.s[0][3]=-1; E.s[1][0]=1,E.s[1][1]=0,E.s[1][2]=0,E.s[1][3]=0; E.s[2][0]=0,E.s[2][1]=1,E.s[2][2]=0,E.s[2][3]=0; E.s[3][0]=0,E.s[3][1]=0,E.s[3][2]=1,E.s[3][3]=0; Matrix B(5,5); B.s[0][0]=36,B.s[1][0]=11,B.s[2][0]=5,B.s[3][0]=1; long long n; while(~scanf("%lld",&n)){ if(n<=4) cout<<B.s[4-n][0]<<endl; else { Matrix ans=E^(n-4); ans=ans*B; cout<<(ans.s[0][0]+mod)%mod<<endl; } } }

當然 既然確定是線性遞推,直接套杜教模板也是可以的。。。。。。。。