棋盘覆盖 状压DP+矩阵快速幂
题意:有一个m 行n 列的矩形方格棋盘,1 < = m< = 5,1=< n< =10^9,用1*2 的骨牌(可横放或竖放)完全覆盖,骨牌不能重叠,有多少种不同的覆盖的方法。你只需要求出覆盖方法总数 mod p 的值即可。
看到1e9立马知道快速幂DP或者数学方法,然后m<=5就状压吧
定义f[s][t]表示从s到t有多少种方案转移:则有f[s][t] = sigma(f[s][i] * f[i][t]) 所以可以用矩阵转移
最终答案就是f[(1<<m)-1][(1<<m)-1]
预处理一下两个状态能否转移到就可以矩阵加速DP了
Code:
#include <bits/stdc++.h>
using namespace std;
const int MAXS = 32;
int n, m, p;
struct Matrix
{
int M[MAXS][MAXS];
Matrix(){ memset(M, 0, sizeof M); }
friend Matrix operator * (const Matrix &A, const Matrix &B)
{
Matrix C;
for(int k = 0; k < (1<<m); k++)
for(int i = 0; i < (1<<m); i++) if(A.M[i][k])
for(int j = 0; j < (1<<m); j++) if(B.M[k][j])
C.M[i][j] = (1ll * A.M[i][k] * B.M[k][j] % p + C.M[i][j]) % p;
return C;
}
};
bool check(int s, int t)
{
int left = 0;
for(int i = 0; i < m; i++)
if((s&(1<<i)) && (t&(1<<i)))
(++left) %= 2;
else
{
if(left) return 0;
if(!(s&(1<<i)) && !(t&(1<<i)))
return 0;
}
return left ? 0 : 1;
}
void Pow(Matrix &a, int b, Matrix &ret)
{
ret = a;
if(!b) return;
while(b)
{
if(b & 1) ret = ret * a;
a = a * a; b >>= 1;
}
return;
}
int main ()
{
Matrix a, ans;
scanf("%d%d%d", &n, &m, &p);
for(int s = 0; s < (1<<m); s++)
for(int t = 0; t < (1<<m); t++)
a.M[s][t] = check(s, t);//预处理
Pow(a, n-1, ans);
printf("%d\n", ans.M[(1<<m)-1][(1<<m)-1]);
}
注意预处理s能否到达t时只能
(1)横着放在两列
或
(2)在t那一列竖着
因为只在s那一列放不属于本次转移
棋盘覆盖 状压DP+矩阵快速幂的更多相关文章
- BZOJ4000 TJOI2015棋盘(状压dp+矩阵快速幂)
显然每一行棋子的某种放法是否合法只与上一行有关,状压起来即可.然后n稍微有点大,矩阵快速幂即可. #include<iostream> #include<cstdio> #in ...
- HDU 5434 Peace small elephant 状压dp+矩阵快速幂
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: ...
- 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂
[题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...
- BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )
状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...
- [BZOJ4000][TJOI2015]棋盘(状压DP+矩阵快速幂)
题意极其有毒,注意给的行列都是从0开始的. 状压DP,f[i][S]表示第i行状态为S的方案数,枚举上一行的状态转移.$O(n2^{2m})$ 使用矩阵加速,先构造矩阵a[S1][S2]表示上一行为S ...
- 【BZOJ4000】【LOJ2104】【TJOI2015】棋盘 (状压dp + 矩阵快速幂)
Description 有一个\(~n~\)行\(~m~\)列的棋盘,棋盘上可以放很多棋子,每个棋子的攻击范围有\(~3~\)行\(~p~\)列.用一个\(~3 \times p~\)的矩阵给出了 ...
- 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT
题目大意 给你一个网格,每个格子有概率是\(1\)或是\(0\).告诉你每个点是\(0\)的概率,求\(1\)的连通块个数\(\bmod d=0\)的概率. 最开始所有格子的概率相等.有\(q\)次修 ...
- 2018.09.28 hdu5434 Peace small elephant(状压dp+矩阵快速幂)
传送门 看到n的范围的时候吓了一跳,然后发现可以矩阵快速幂优化. 我们用类似于状压dp的方法构造(1(1(1<<m)∗(1m)*(1m)∗(1<<m)m)m)大小的矩阵. 然后 ...
- BZOJ 2004 公交线路(状压DP+矩阵快速幂)
注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...
随机推荐
- API总结
1. 什么是Webservice WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API,也就是说能用编程的方法通过 Web 来调用这个应用程序.我们把调用这个WebServ ...
- yii2 发送邮件 yii\swiftmailer\Mailer
Yii2 中发送邮件 yii\swiftmailer\Mailer 'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', 'viewPath ...
- 面试4 --- constructor必须与class同名,但方法不能与class同名?
选 C “constructor必须与class同名,但方法不能与class同名”这句话是错误的,方法是可以和class同名的:方法可以和类名同名的,和构造方法唯一的区别就是,构造方法没有返回值.
- ElasticSerach 6.x的安装及配置
1.准备工作 安装Centos7.建议内存2G以上.安装java1.8环境,固定IP地址,本文省略. 2.ElasticSerach单机安装 1) 创建/opt/es目录,存放文件ElasticSer ...
- centos7 设置 查看 开机 启动项
1.查看开机自启项centos7自启项已不用chkconfig改为:systemctl list-unit-files左边是服务名称,右边是状态,enabled是开机启动,disabled是开机不启动 ...
- 【洛谷 P3041】 [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机,dp)
题目链接 手写一下AC自动机(我可没说我之前不是手写的) Trie上dp,每个点的贡献加上所有是他后缀的串的贡献,也就是这个点到根的fail链的和. #include <cstdio> # ...
- 大学课后答案微信小程序项目实践(1)
叨逼叨 还记得以前小编上大学那会苦于课后习题没有答案...到了考试....就像下面这个图一样- 现在,那些同样在纠结于书本后的答案太遥远的同学们,要告诉你们一个好消息,个人历时两周作业的时间开发的小程 ...
- LinuxKernel优秀博客
1.vanbreaker的专栏 2.LinuxKernel Exploration 3.DroidPhone的专栏 4.Linux内核研究以及学习文档和ARM学习以及研究的开放文档 [力荐] 5. ...
- mysql死锁检查
1.查看当前数据库进程 show processlist; show full processlist; #前者只显示前100条,后者显示所有的进程 2.一键杀死某个用户的所有进程 select ...
- SQL SERVER-3种连接
Nested Loops Join Merge Join Hash Join