洛谷P1357 花园(状态压缩 + 矩阵快速幂加速递推)
题目链接:传送门
题目:
题目描述 小L有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为1~N(<=N<=^)。他的环形花园每天都会换一个新花样,但他的花园都不外乎一个规则,任意相邻M(<=M<=,M<=N)个花圃中有不超过K(<=K<M)个C形的花圃,其余花圃均为P形的花圃。 例如,N=,M=,K=。则 CCPCPPPPCC 是一种不符合规则的花圃; CCPPPPCPCP 是一种符合规则的花圃。 请帮小L求出符合规则的花园种数Mod 由于请您编写一个程序解决此题。
输入输出格式
输入格式: 一行,三个数N,M,K。 输出格式: 花园种数Mod 输入输出样例
输入样例#: 输出样例#: 输入样例#: 输出样例#: 说明 【数据规模】 %的数据中,N<=; %的数据中,M=; %的数据中,N<=^。 %的数据中,N<=^。
思路:
乍一看是一个环形dp:
对于给定的长度为M的状态,其后面长度为M-1的部分会影响下一个状态,记一个cnt1表示已经放了C型花圃的数量,那么根据当前的cnt1是否小于K,可以决定下个状态的转移。
状态:
f[i][j]:以第i个位置为终点的长度为M的部分,状态为j的方案数。(j是用2进制状压的一个长度为M的状态)
状态转移方程:
f[i][j] += f[i-1][j>>1];
if (count1(j) == K && !(j&1))
f[i][j] += f[i-1][(j>>1)|(1<<M)];
。。。。。。
但是N的上限高达1e15,所以常规的方法没发跑,考虑用矩阵加速。
那就要找状态矩阵和转移矩阵了。
状态矩阵:
Fn = [f[n][0], f[n][1], ... , f[n][(1<<m)-1];
转移矩阵可以通过上面的状态转移方程,用dfs预处理出来,接下来就可以用快速幂加速了。
因为跑N次之后和不跑的时候状态相同(环形),所以直接求转移矩阵A的N次AN的对角线上的和即可。
代码:
#include <bits/stdc++.h> using namespace std;
typedef long long ll;
const int MOD = 1e9 + ; ll N, M, K;
int bin[];
ll F[][], A[][]; void addTran(int sta, int cnt1)
{
int pre = sta >> ;
A[pre][sta] = ;
if (cnt1 == K && !(sta&))
return;
A[pre|bin[M-]][sta] = ;
} void dfs(int dep, int sta, int cnt1)
{
if (dep == M) {
addTran(sta, cnt1);
return;
}
dfs(dep+, sta, cnt1);//dep+1位为0
if (cnt1 < K && dep+ < M)
dfs(dep+, sta|bin[dep+], cnt1+);//dep+1位为1
} void mul(ll f[][], ll a[][])
{
ll c[][];
memset(c, , sizeof c);
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
for (int k = ; k < ; k++)
c[i][j] = (c[i][j] + f[i][k] * a[k][j]) % MOD;
memcpy(f, c, sizeof c);
} int main()
{
bin[] = ;
for (int i = ; i <= ; i++)
bin[i] = bin[i-] << ;
cin >> N >> M >> K;
memset(A, , sizeof A);
memset(F, , sizeof F);//所有长度为M的状态
for (int i = ; i < bin[M]; i++)
F[i][i] = ;
dfs(, , );//初始化转移矩阵
dfs(, , );
for (; N; N >>= ) {
if (N&)
mul(F, A);
mul(A, A);
}
ll ans = ;
for (int i = ; i < bin[M]; i++)
ans = (ans + F[i][i]) % MOD;
cout << ans << endl;
return ;
}
/*
6 2 1
*/
洛谷P1357 花园(状态压缩 + 矩阵快速幂加速递推)的更多相关文章
- CH 3401 - 石头游戏 - [矩阵快速幂加速递推]
题目链接:传送门 描述石头游戏在一个 $n$ 行 $m$ 列 ($1 \le n,m \le 8$) 的网格上进行,每个格子对应一种操作序列,操作序列至多有 $10$ 种,分别用 $0 \sim 9$ ...
- HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 Farmer John likes to play mathematics games with ...
- HDU 1757 矩阵快速幂加速递推
题意: 已知: 当x<10时:f(x)=x 否则:f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + --+ a9 * f(x-10); 求:f(x ...
- luogu1357 花园 状态压缩 矩阵快速幂
题目大意 小L有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为1~N(2<=N<=10^15).他的环形花园每天都会换一个新花样,但他的花园都不外乎一个规则,任意相邻M(2<= ...
- CH3401 石头游戏(矩阵快速幂加速递推)
题目链接:传送门 题目: 石头游戏 0x30「数学知识」例题 描述 石头游戏在一个 n 行 m 列 (≤n,m≤) 的网格上进行,每个格子对应一种操作序列,操作序列至多有10种,分别用0~9这10个数 ...
- [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)
Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...
- [bzoj1008](HNOI2008)越狱(矩阵快速幂加速递推)
Description 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 In ...
- HDU5950 Recursive sequence (矩阵快速幂加速递推) (2016ACM/ICPC亚洲赛区沈阳站 Problem C)
题目链接:传送门 题目: Recursive sequence Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total ...
- POJ3070 Fibonacci(矩阵快速幂加速递推)【模板题】
题目链接:传送门 题目大意: 求斐波那契数列第n项F(n). (F(0) = 0, F(1) = 1, 0 ≤ n ≤ 109) 思路: 用矩阵乘法加速递推. 算法竞赛进阶指南的模板: #includ ...
随机推荐
- JS设计模式(6)命令模式
什么是命令模式? 定义:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化. 主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录. ...
- 在pycharm中开发vue
一.在pycharm中开发vue ''' webstorm(vue) pycharm(python) goland(Go语言) idea(java) andrioStuidio(安卓) Php(PHP ...
- 代码覆盖率-JaCoCo
代码覆盖率 在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%. JaCoCo Jacoco从多种角度对代码 ...
- while循环和递归
这个问题是在数据结构的二叉树添加结点的时候碰见 添加新结点的时候可以用while循环自身解决(这里这个方式更好) 也可以用递归解决 递归就像小明去楼顶取东西 ,从一楼开始爬,看,不是的,继续爬,每层 ...
- 《Practical Vim》第十章:复制和粘贴
第十章和第十一章讲了 Vim 的寄存器功能, 寄存器,是用于保存文本的特定的容器.它的内容: 既可以是类似于系统剪切板功能的,用于粘贴的文本 也可以是录制成的宏的命令. 第十章讲使用寄存器使用复制与粘 ...
- CentOS7.5下安装Python3.7 --python3
1.将本地安装包上传到远程主机上 scp Python-3.7.0.tgz root@123.206.74.24:/root 2.扩展 安装Python之前安装Python相关的依赖包(主要是u红色部 ...
- ionic3 双向数据绑定失效 脏值检测失效
最近在使用ionic3过程中,使用了eval()方法进行字符串拼接成一个function使用 在eval()方法中,只能使用局部变量,全局变量无法使用,ionic3的this在eval中失效(unde ...
- js的Timer方法
如显示时间: <script> //获取时间 function mytime(){ var a = new Date(); var b = a.toLocaleTimeString(); ...
- spring整合junit报错
1.Could not autowire field: private javax.servlet.http.HttpServletRequest 参考:https://www.cnblogs.com ...
- 修改host文件——mac
打开终端 在终端terminal中输入sudo vi/etc/hosts sudo与vi之间有一个空格 上一步输入完成之后按回车键,如果当前用户账号有密码,则在按完之后会提示输入密码,此时输入当前账户 ...