洛谷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 ...
随机推荐
- 王之泰201771010131《面向对象程序设计(java)》第七周学习总结
王之泰201771010131<面向对象程序设计(java)>第七周学习总结 第一部分:理论知识学习部分 第五章 第五章内容深度学习: 继承:如果两个类存在继承关系,则子类会自动继承父类的 ...
- HAProxy + Keepalived + Flume 构建高性能高可用分布式日志系统
一.HAProxy简介 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代 理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点, ...
- 多台linux主机间免密码登录
即在一台主机上登录另一台主机. 有2台linux主机A.B.A输入命令ssh B的ip地址以连接B,发现需要输入B的登录密码,怎样不需要输入密码呢? 步骤1: 在主机A中,输入ssh-keygen - ...
- 微信小程序wepy开发循环wx:for需要注意
微信小程序wepy开发循环wx:for需要注意 item index值必须在wx:for之后使用 <view wx:for="{{tablist}}" class=" ...
- Latex: 参考文献双栏对齐
参考: How to level columns in bibliography? Latex: 参考文献双栏对齐 需要实现的效果: 方法1: 在开头引用balance: \usepackage{ba ...
- CSS--交互效果
动画过渡效果 //vue <div class="search-list" v-show="searches.length"> <transi ...
- 一: DRF web应用框架基础,及序列化器的使用
---恢复内容开始--- 一: web 应用模式(有两种) 1: 前后端不分离(前端从后端直接获取数据) 2: 前后端分离 二: api 接口 原因一: 为了在团队内部形成共识.防止个人习惯差异引起的 ...
- java jdk动态代理学习记录
转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...
- [python]python2与python3版本的区别
python2和python3的区别 区别: print函数 整数相除 Unicode 异常处理 xrange map函数 不支持has_key print函数: Python 2: print是语句 ...
- 脚本可执行,但无HTML测试报告文件生成,其造成的原因是在PyCharm的执行模式错误
定义测试报告两种写法: 1)测试报告直接在本地绝对路径下生成 # 导入HTMLTestRunner模块 import HTMLTestRunner # 通过open()方法以二进制写模式('wb')打 ...