poj 3420 Quad Tiling 【矩阵乘法】
2013-04-10 01:27
507 查看
http://poj.org/problem?id=3420
题目大意:求在一个4*N(N<=1000000000)的格子中放1*2的格子的方案数。
首先推导出公式f(n)=f(n-1)+5f(n-2)+f(n-3)-f(n-4),然后将其用矩阵乘法进行优化。
矩阵的转换看这里:http://www.cnblogs.com/aiiYuu/gallery/image/127131.html
然后用矩阵连乘进行运算,将复杂度降到了O(logN)。
题目大意:求在一个4*N(N<=1000000000)的格子中放1*2的格子的方案数。
首先推导出公式f(n)=f(n-1)+5f(n-2)+f(n-3)-f(n-4),然后将其用矩阵乘法进行优化。
矩阵的转换看这里:http://www.cnblogs.com/aiiYuu/gallery/image/127131.html
然后用矩阵连乘进行运算,将复杂度降到了O(logN)。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <set> #include <map> #include <cmath> #include <queue> using namespace std; template <class T> void checkmin(T &t,T x) {if(x < t) t = x;} template <class T> void checkmax(T &t,T x) {if(x > t) t = x;} template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;} template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;} typedef pair <int,int> PII; typedef pair <double,double> PDD; typedef long long ll; #define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++) const int N = 4; int n , MOD; struct Matrix { int n , m; int a ; Matrix() {} Matrix(int _n,int _m):n(_n),m(_m){}; void intput() { for(int i=0;i<n;i++) for(int j=0;j<m;j++) scanf("%d",&a[i][j]); } Matrix operator + (const Matrix &b) { Matrix tmp = Matrix(n,m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) tmp.a[i][j] = a[i][j] + b.a[i][j]; return tmp; } Matrix operator - (const Matrix &b) { Matrix tmp = Matrix(n,m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) tmp.a[i][j] = a[i][j] - b.a[i][j]; return tmp; } Matrix operator * (const Matrix &b) { Matrix tmp = Matrix(n,b.m); for(int i=0;i<n;i++) for(int j=0;j<b.m;j++) tmp.a[i][j] = 0; for(int i=0;i<n;i++) for(int j=0;j<b.m;j++) for(int k=0;k<m;k++) { tmp.a[i][j] += a[i][k]*b.a[k][j]; tmp.a[i][j] %= MOD; } return tmp; } }; Matrix operator ^ (Matrix a , int p) { Matrix ret = Matrix(a.n,a.m); for(int i=0;i<a.n;i++) for(int j=0;j<a.m;j++) ret.a[i][j] = (i == j ? 1 : 0); while(p) { if(p%2) ret = ret * a; a = a * a; p /= 2; } return ret; } /* Matrix mi(Matrix a , int p) { Matrix tmp = Matrix(a.n,a.m); for(int i=0;i<a.n;i++) for(int j=0;j<a.m;j++) if(i==j) tmp.a[i][j]=1; else tmp.a[i][j]=0; if(p == 0) return tmp; if(p == 1) return a; if(p % 2) tmp = a; Matrix tt = mi(a , p/2); return tt * tt * tmp; }*/ Matrix A , h; int main() { while(~scanf("%d%d",&n,&MOD) && n+MOD) { h = Matrix(4,4); h.a[0][0]=1; h.a[1][0]=5; h.a[2][0]=11; h.a[3][0]=36; A = Matrix(4,4); A.a[0][0]=0;A.a[0][1]=1;A.a[0][2]=0;A.a[0][3]=0; A.a[1][0]=0;A.a[1][1]=0;A.a[1][2]=1;A.a[1][3]=0; A.a[2][0]=0;A.a[2][1]=0;A.a[2][2]=0;A.a[2][3]=1; A.a[3][0]=-1;A.a[3][1]=1;A.a[3][2]=5;A.a[3][3]=1; A = A ^ (n-1); A = A * h; printf("%d\n" , A.a[0][0]); } return 0; }
相关文章推荐
- poj3420 Quad Tiling 矩阵乘法
- POJ-3420 Quad Tiling 状态压缩+矩阵乘法
- POJ 3420 Quad Tiling (矩阵乘法)
- POJ 3420 Quad Tiling (瓷砖问题+矩阵快速幂)
- poj 3420 Quad Tiling(状态压缩矩阵递推)
- Quad Tiling POJ - 3420 矩阵快速幂
- POJ_3420_Quad Tiling_搜索,矩阵快速幂,状态压缩,动态规划
- POJ 3420 Quad Tiling 线性递推 矩阵快速幂
- Quad Tiling - POJ 3420 矩阵递推
- POJ 3420 Quad Tiling(状压DP 用矩阵快速幂优化)
- POJ - 3420 Quad Tiling (矩阵快速幂)
- Quad Tiling POJ - 3420 (矩阵快速幂)题解
- poj 3420 Quad Tiling
- POJ 3420 矩阵乘法
- POJ 3420 Quad Tiling
- POJ 3420 Quad Tiling
- [POJ 3420]Quad Tiling(状压DP+矩阵乘法)
- POJ 3420 Quad Tiling 状压DP+矩阵快速幂
- 【POJ 3420】Quad Tiling(dp|递推 +矩阵快速幂)
- POJ 3420 Quad Tiling