[vijos 1194]Domino(矩阵乘法)
2009-10-08 13:52
267 查看
【题目大意】:
n*m的棋盘,让你用1*2的骨牌完全覆盖,问有多少种方案。(m<=5,n<=10^9)
【题目分析】:
最开始我就往状压dp上想,但是发现这个n太大,不仅空间承受不了,时间也是不允许的。
想了很久,没有思路,所以决定去看看题解。
果然这个题有很神的算法。
标准算法:矩阵乘法。
我们将问题抽象化一下,在整个棋盘上,只有相邻两行有关联。这种想法类似状压dp。
这样一些状态之间就有转化关系。
这些状态通过一系列的转化,经过了n行,得到了1111……(满状态)
所以这个问题就转化成了:给你一个图,问从一个点出发经过n步正好回到原来的点的路径的个数。
这个就有一个经典的算法就是矩阵乘法。
将图的邻接矩阵进行乘方,矩阵的n次方得到的矩阵中[i,j]元素表示从i走到j经过正好n步的路径个数。
那么这个问题就很好解决了,方法就是找到状态之间的联系,得出矩阵。
然后快速幂乘方,得到矩阵的[1<<m-1,1<<m-1]元素即为所求。
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
├ 测试数据 08:答案正确... 0ms
├ 测试数据 09:答案正确... 0ms
├ 测试数据 10:答案正确... 0ms
├ 测试数据 11:答案正确... 0ms
├ 测试数据 12:答案正确... 0ms
├ 测试数据 13:答案正确... 0ms
├ 测试数据 14:答案正确... 0ms
├ 测试数据 15:答案正确... 0ms
├ 测试数据 16:答案正确... 0ms
├ 测试数据 17:答案正确... 0ms
├ 测试数据 18:答案正确... 0ms
├ 测试数据 19:答案正确... 0ms
├ 测试数据 20:答案正确... 0ms
├ 测试数据 21:答案正确... 0ms
├ 测试数据 22:答案正确... 0ms
├ 测试数据 23:答案正确... 0ms
├ 测试数据 24:答案正确... 0ms
├ 测试数据 25:答案正确... 0ms
-------------------------
Accepted 有效得分:100 有效耗时:0ms
【代码】:
n*m的棋盘,让你用1*2的骨牌完全覆盖,问有多少种方案。(m<=5,n<=10^9)
【题目分析】:
最开始我就往状压dp上想,但是发现这个n太大,不仅空间承受不了,时间也是不允许的。
想了很久,没有思路,所以决定去看看题解。
果然这个题有很神的算法。
标准算法:矩阵乘法。
我们将问题抽象化一下,在整个棋盘上,只有相邻两行有关联。这种想法类似状压dp。
这样一些状态之间就有转化关系。
这些状态通过一系列的转化,经过了n行,得到了1111……(满状态)
所以这个问题就转化成了:给你一个图,问从一个点出发经过n步正好回到原来的点的路径的个数。
这个就有一个经典的算法就是矩阵乘法。
将图的邻接矩阵进行乘方,矩阵的n次方得到的矩阵中[i,j]元素表示从i走到j经过正好n步的路径个数。
那么这个问题就很好解决了,方法就是找到状态之间的联系,得出矩阵。
然后快速幂乘方,得到矩阵的[1<<m-1,1<<m-1]元素即为所求。
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
├ 测试数据 08:答案正确... 0ms
├ 测试数据 09:答案正确... 0ms
├ 测试数据 10:答案正确... 0ms
├ 测试数据 11:答案正确... 0ms
├ 测试数据 12:答案正确... 0ms
├ 测试数据 13:答案正确... 0ms
├ 测试数据 14:答案正确... 0ms
├ 测试数据 15:答案正确... 0ms
├ 测试数据 16:答案正确... 0ms
├ 测试数据 17:答案正确... 0ms
├ 测试数据 18:答案正确... 0ms
├ 测试数据 19:答案正确... 0ms
├ 测试数据 20:答案正确... 0ms
├ 测试数据 21:答案正确... 0ms
├ 测试数据 22:答案正确... 0ms
├ 测试数据 23:答案正确... 0ms
├ 测试数据 24:答案正确... 0ms
├ 测试数据 25:答案正确... 0ms
-------------------------
Accepted 有效得分:100 有效耗时:0ms
【代码】:
program vijos_1194; type matrix=array[0..32,0..32] of longint; var ans,g:matrix; n,m,p,i,j,k:longint; flag:boolean; function multi(a,b:matrix):matrix; var ans:matrix; i,j,k:longint; begin fillchar(ans,sizeof(ans),0); for i:=0 to 1 shl m-1 do for j:=0 to 1 shl m-1 do for k:=0 to 1 shl m-1 do ans[i,j]:=(ans[i,j]+a[i,k]*b[k,j]) mod p; exit(ans); end; begin assign(input,'a.in'); assign(output,'a.out'); reset(input); rewrite(output); readln(n,m,p); for i:=0 to 1 shl m-1 do for j:=0 to 1 shl m-1 do if (i or j=1 shl m-1) and ((i and j) in [0,3,6,12,15,24,27,30]) then g[i,j]:=1; flag:=false; for i:=0 to (1 shl m-1) do ans[i,i]:=1; while n>0 do begin if n mod 2=1 then ans:=multi(ans,g); g:=multi(g,g); n:=n div 2; end; writeln(ans[(1 shl m-1),(1 shl m-1)]); close(input); close(output); end.
相关文章推荐
- [Vijos 1194] Domino · 矩阵乘法 (附运算符优先级表)
- [caioj 1487及vijos 1194,利用矩阵乘法解决的经典题目九]有趣的domino
- 矩阵——vijos1194 Domino
- [Vijos 1049] 送给圣诞夜的礼品 · 矩阵乘法
- [caioj 1485及vijos 1067,利用矩阵乘法解决的经典题目七]童年的走格子
- 矩阵乘法学习笔记(二)(vijos1049+vijos1067)
- vijos1194 Domino
- Vijos 1603 ----迷宫(矩阵乘法,矩阵快速幂)
- [BZOJ 2875 & Vijos 1725] NOI 2012 随机数生成器 · 矩阵乘法+快速乘法
- vijosP1194 Domino
- 【vijos1067】【矩阵乘法】守望者的烦恼
- [caioj 1482及vijos 1049,利用矩阵乘法解决的经典题目四]序列无限变
- vijosP1194 Domino 状压DP+矩阵优化
- [Vijos 1067] Warcraft III 守望者的烦恼 · 矩阵乘法
- 矩阵乘法-vijos1603迷宫
- 由vijos1067 联想到的矩阵乘法
- [Vijos 1603] 迷宫 · 矩阵乘法
- 【vijos1049】【矩阵乘法】送给圣诞夜的礼品
- hpu-【1035: 矩阵乘法】
- 矩阵乘法的MPI并行计算