【POJ 3420】Quad Tiling(dp|递推 +矩阵快速幂)
2016-10-27 20:47
344 查看
**
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4122 Accepted: 1885
Description
Tired of the Tri Tiling game finally, Michael turns to a more challengeable game, Quad Tiling:
In how many ways can you tile a 4 × N (1 ≤ N ≤ 109) rectangle with 2 × 1 dominoes? For the answer would be very big, output the answer modulo M (0 < M ≤ 105).
Input
Input consists of several test cases followed by a line containing double 0. Each test case consists of two integers, N and M, respectively.
Output
For each test case, output the answer modules M.
Sample Input
1 10000
3 10000
5 10000
0 0
Sample Output
1
11
95
Source
POJ Monthly–2007.10.06, Dagger
【题解】【递推+矩阵快速幂】
【刚开始,推式子ing….一段漫长而依赖std的时光】
【result : f[i]=f[i-1]+5*f[i-2]+f[i-3]-f[i-4]】
【具体这个式子是如何得来的?呵呵,我可不可以说我是凑的?!(我刚开始用f[1]、f[2]凑f[3],然后发现f[4]不满足,failed! 然后,用f[1]、f[2]、f[3]凑f[4],然后,f[5]不满足,failed!然后,我用前四个凑f[5],往后试了几个,发现accept!)】
【好了,朴素的算法已经得出,那么,构造矩阵即可】
初始矩阵为: {f[4],f[3],f[2],f[1]} => {36,11,5,1}
转移矩阵为:⎡⎣⎢⎢⎢1,1,0,05,0,1,01,0,0,1−1,0,0,0⎤⎦⎥⎥⎥
【注意:转移矩阵在进行快速幂时,需要%m,但由于有负数需要+m%m】
Quad Tiling
**Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4122 Accepted: 1885
Description
Tired of the Tri Tiling game finally, Michael turns to a more challengeable game, Quad Tiling:
In how many ways can you tile a 4 × N (1 ≤ N ≤ 109) rectangle with 2 × 1 dominoes? For the answer would be very big, output the answer modulo M (0 < M ≤ 105).
Input
Input consists of several test cases followed by a line containing double 0. Each test case consists of two integers, N and M, respectively.
Output
For each test case, output the answer modules M.
Sample Input
1 10000
3 10000
5 10000
0 0
Sample Output
1
11
95
Source
POJ Monthly–2007.10.06, Dagger
【题解】【递推+矩阵快速幂】
【刚开始,推式子ing….一段漫长而依赖std的时光】
【result : f[i]=f[i-1]+5*f[i-2]+f[i-3]-f[i-4]】
【具体这个式子是如何得来的?呵呵,我可不可以说我是凑的?!(我刚开始用f[1]、f[2]凑f[3],然后发现f[4]不满足,failed! 然后,用f[1]、f[2]、f[3]凑f[4],然后,f[5]不满足,failed!然后,我用前四个凑f[5],往后试了几个,发现accept!)】
【好了,朴素的算法已经得出,那么,构造矩阵即可】
初始矩阵为: {f[4],f[3],f[2],f[1]} => {36,11,5,1}
转移矩阵为:⎡⎣⎢⎢⎢1,1,0,05,0,1,01,0,0,1−1,0,0,0⎤⎦⎥⎥⎥
【注意:转移矩阵在进行快速幂时,需要%m,但由于有负数需要+m%m】
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct node{ long long k[5][5]; }d; int f[5],n,m,ans; inline node jc(node a,node b) { node c; memset(c.k,0,sizeof(c.k)); for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) for(int l=1;l<=4;++l) { long long sm=a.k[i][l]*b.k[l][j]; sm=((sm+m)%m+m)%m; c.k[i][j]=(c.k[i][j]+sm)%m; } return c; } node poww(node x,int p) { if(p==1) return d; if(p%2==0) { node a=poww(x,p/2); a=jc(a,a); return a; } else { node a=poww(x,p/2); a=jc(a,a); a=jc(a,x); return a; } } inline int solve(int p) { node as=poww(d,p); int sum[5]; memset(sum,0,sizeof(sum)); for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) sum[j]=(sum[j]+as.k[i][j]*f[i]%m)%m; return sum[1]; } int main() { //freopen("int.txt","r",stdin); //freopen("my.txt","w",stdout); f[1]=36; f[2]=11; f[3]=5; f[4]=1; d.k[1][1]=d.k[1][2]=d.k[2][3]=d.k[3][1]=d.k[3][4]=1; d.k[2][1]=5; d.k[4][1]=-1; while((scanf("%d%d",&n,&m)==2)&&!(n==0&&m==0)) { if(n==1||n==2||n==3||n==4) {printf("%d\n",f[4-n+1]%m); continue;} ans=solve(n-4); printf("%d\n",ans); } }
相关文章推荐
- Quad Tiling - POJ 3420 矩阵递推
- POJ 3420 Quad Tiling 线性递推 矩阵快速幂
- poj 3420 Quad Tiling(状态压缩矩阵递推)
- poj 3420 Quad Tiling 状压dp
- poj 3420 Quad Tiling 【矩阵乘法】
- poj3420 Quad Tiling 矩阵乘法
- poj3420 Quad Tiling
- POJ 3420 Quad Tiling
- POj 3420 Quad Tiling 状态压缩DP+递推+矩阵快速幂
- POJ-3420 Quad Tiling 状态压缩+矩阵乘法
- POJ 3420 Quad Tiling
- POJ_3420_Quad Tiling_搜索,矩阵快速幂,状态压缩,动态规划
- POJ 3420 Quad Tiling(状压DP 用矩阵快速幂优化)
- POJ 3420 Quad Tiling (瓷砖问题+矩阵快速幂)
- POJ - 3420 Quad Tiling (矩阵快速幂)
- Quad Tiling [POJ 3420]
- [POJ 3420]Quad Tiling(状压DP+矩阵乘法)
- POJ3420 Quad Tiling
- POJ3420-Quad Tiling
- POJ_3420_Quad Tiling