【矩阵乘法】Quad Tiling(poj 3420)
生活随笔
收集整理的這篇文章主要介紹了
【矩阵乘法】Quad Tiling(poj 3420)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Quad Tiling
poj 3420
題目大意
在一個4×n的棋盤上,用1×2的多米諾骨牌把他填滿,問有多少種方法
輸入樣例
1 10000 3 10000 5 10000 0 0輸出樣例
1 11 95數據范圍
1?N?1091 \leqslant N \leqslant 10^91?N?109
0<M?1050 < M \leqslant 10^50<M?105
解題思路
對于放多米諾骨牌可以用狀壓DP
但直接狀壓會TLE
考慮矩陣乘法
可以先把狀態之間的關系預處理出來
然后快速冪即可
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define wyc mod using namespace std; ll n, mod; struct matrix {ll n, m, a[20][20];matrix operator *(const matrix &b) const{matrix c;c.n = n;c.m = b.m;for (int i = 1; i <= c.n; ++i)for (int j = 1; j <= c.m; ++j)c.a[i][j] = 0;for (int i = 1; i <= c.n; ++i)for (int k = 1; k <= m; ++k)for (int j = 1; j <= c.m; ++j)c.a[i][j] = (c.a[i][j] + a[i][k] * b.a[k][j] % wyc) % wyc;return c;} }A, B; ll ggg(ll x, ll y, ll z, ll g) {return x + (y<<1) + (z<<2) + (g<<3) + 1; } void pp(ll x, ll y, ll z, ll g) {ll xx = x^1, yy = y^1, zz = z^1, gg = g^1;B.a[ggg(xx, yy, zz, gg)][ggg(x, y, z, g)] = 1;if (!xx && !yy){B.a[ggg(1, 1, zz, gg)][ggg(x, y, z, g)] = 1;if (!zz && !gg)B.a[ggg(1, 1, 1, 1)][ggg(x, y, z, g)] = 1;}if (!yy && !zz)B.a[ggg(xx, 1, 1, gg)][ggg(x, y, z, g)] = 1;if (!zz && !gg)B.a[ggg(xx, yy, 1, 1)][ggg(x, y, z, g)] = 1;return; } void Counting(ll x) {while(x){if (x&1) A = A * B;B = B * B;x>>=1; }return; } int main() {while(1){scanf("%lld%lld", &n, &mod);if (!n) break;for (int i = 1; i <= 16; ++i){A.a[1][i] = 0;for (int j = 1; j <= 16; ++j)B.a[i][j] = 0;}A.n = 1;A.m = B.n = B.m = 16;A.a[1][1] = 1;//初始狀態A.a[1][4] = 1;A.a[1][7] = 1;A.a[1][13] = 1;A.a[1][16] = 1;for (int i = 0; i <= 1; ++i)for (int j = 0; j <= 1; ++j)for (int k = 0; k <= 1; ++k)for (int c = 0; c <= 1; ++c)pp(i, j, k, c);//預處理矩陣Counting(n - 1);//快速冪printf("%lld\n", A.a[1][16] % wyc);}return 0; }總結
以上是生活随笔為你收集整理的【矩阵乘法】Quad Tiling(poj 3420)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel大小转换技巧,轻松掌握,文本管
- 下一篇: 【矩阵乘法】生成树计数(luogu 21