题目链接

题目

题目描述

给一个m x n的方格,Applese想要给方格填上颜色,每个格子可以是黑色或者白色。他要求左右相邻两格不能同为白色且相邻两列不能全为黑色。

求满足条件的方案数。

输入描述

输入两个整数m, n。\((1 ≤ m ≤ 5, 1 ≤ n ≤ 10^{18})\)。

输出描述

输出答案对 \(10^9 + 7\) 取模的结果。

**示例1 **

输入

3 1

输出

8

示例2

输入

3 5

输出

1640

示例3

输入

5 5

输出

351032

题解

知识点:状压dp,运算优化。

注意到可以一列一列摆,设 \(0\) 代表黑色,\(1\) 代表白色,这样比反过来方便。设第 \(i\) 列状态为 \(st1\) ,第 \(i-1\) 列状态为 \(st2\) ,于是首先 \(st1\) 和 \(st2\) 自己都要满足 st & (st<<1) 不能为 \(1\) ,即相邻不为白色,随后 st1 & st2 必须大于 \(0\) ,即两列不能都为黑色。设 \(dp[i][st]\) 表示摆到第 \(i\) 列,状态 \(st\) 时的方案数,有转移方程:

\[dp[i][st1] = \sum dp[i-1][st2]
\]

注意到 \(n\) 十分的大,考虑优化。发现转移方程只和这一列的 \(st1\) 和上一列的 \(st2\) 有关,并且对于一组 \((st1,st2)\) 能否转移是不随 \(i\) 变化的,因此我们可以预先确定每一组 \((st1,st2)\) 是否可以从 \(st2\) 转移到 \(st1\)。显然,用矩阵快速幂,可以解决这个问题了。假设 $f(i,j) $ ,表示状态 \((i,j)\) 是否可以转移,用 \(01\) 表示,于是 \(f(i,j) = !(i \& j) \and (i | j)\)。矩阵构造如下:

\[\left (
\begin{array}{c}
dp[n][0]\\
dp[n][1]\\
\vdots\\
dp[n][2^m-1]
\end{array}
\right)
=
\left (
\begin{array}{c}
f(0,0) & f(1,0) & \cdots & f(2^m-1,0)\\
f(0,1) & f(1,1) & \cdots & f(2^m-1,1)\\
\vdots & \vdots & \ddots & \vdots\\
f(0,2^m-1) & f(1,2^m-1) & \cdots & f(2^m-1,2^m-1)
\end{array}
\right)
^{n-1}
\left (
\begin{array}{c}
dp[1][0]\\
dp[1][1]\\
\vdots\\
dp[1][2^m-1]
\end{array}
\right)
\]

时间复杂度 \(O(8^m \log n)\)

空间复杂度 \(O(4^m)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; const int mod = 1e9 + 7; ///矩阵快速幂取余,O(n^3logk)
struct Matrix { int n, m;//不能const,快速幂要复制
vector<vector<ll>> mat; explicit Matrix(int _n) :n(_n), m(_n), mat(_n + 1, vector<ll>(_n + 1)) {
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
mat[i][j] = i == j;
}//初始化n阶单位矩阵,explicit防止误用类型转换 Matrix(int _n, int _m) :n(_n), m(_m), mat(_n + 1, vector<ll>(_m + 1)) {}//初始化nxm零矩阵 friend Matrix operator*(const Matrix &A, const Matrix &B) {
Matrix ans(A.n, B.m);
if (A.m != B.n) return ans;
for (int i = 1;i <= A.n;i++)
for (int j = 1;j <= B.m;j++)
for (int k = 1;k <= A.m;k++) //a.m == b.n
ans.mat[i][j] = (ans.mat[i][j] + A.mat[i][k] * B.mat[k][j]) % mod;
return ans;
}//矩阵乘法取余 friend Matrix operator^(Matrix A, ll k) {
Matrix ans(A.n);//A必须是方阵
while (k) {
if (k & 1) ans = ans * A;
k >>= 1;
A = A * A;
}
return ans;
}//快速幂取余 void output() const {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
cout << mat[i][j] << ' ';
cout << '\n';
}
cout << '\n';
}//输出检测
}; int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
ll m, n;
cin >> m >> n;
Matrix init(1 << m, 1);
for (int i = 1;i <= (1 << m);i++)
init.mat[i][1] = 1;
Matrix feat(1 << m, 1 << m);
for (int i = 0;i < (1 << m);i++)
for (int j = 0;j < (1 << m);j++)
feat.mat[i + 1][j + 1] = !(i & j) && (i | j);
Matrix res = (feat ^ (n - 1)) * init;
int ans = 0;
for (int i = 1;i <= (1 << m);i++) ans = (ans + res.mat[i][1]) % mod;
cout << ans << '\n';
return 0;
}

NC17890 方格填色的更多相关文章

  1. java算法 蓝桥杯(题+答案) 方格填数

    6.方格填数  (结果填空) 如下的10个格子 (如果显示有问题,也可以参看[图1.jpg]) 填入0~9的数字.要求:连续的两个数字不能相邻.(左右.上下.对角都算相邻) 一共有多少种可能的填数方案 ...

  2. 蓝桥杯比赛javaB组练习《方格填数》

    方格填数 如下的10个格子   +--+--+--+   |  |  |  |+--+--+--+--+|  |  |  |  |+--+--+--+--+|  |  |  |+--+--+--+ ( ...

  3. java算法 第七届 蓝桥杯B组(题+答案) 6.方格填数

    6.方格填数  (结果填空) 如下的10个格子 (如果显示有问题,也可以参看[图1.jpg]) 填入0~9的数字.要求:连续的两个数字不能相邻.(左右.上下.对角都算相邻) 一共有多少种可能的填数方案 ...

  4. 1002: 当不成勇者的Water只好去下棋了---课程作业---图的填色

    1002: 当不成勇者的Water只好去下棋了 Time Limit: 1 Sec  Memory Limit: 128 MB Description 由于魔王BOSS躲起来了,说好要当勇者的Wate ...

  5. c++_方格填数(最新方法)

      方格填数 如下的10个格子 +--+--+--+ | | | |+--+--+--+--+| | | | |+--+--+--+--+| | | |+--+--+--+ (如果显示有问题,也可以参 ...

  6. 123457123457#0#----com.MC.konglongtianse222----前拼后广--恐龙填色mc-mc1111

    com.MC.konglongtianse222----前拼后广--恐龙填色mc

  7. 123457123456#2#----com.MC.HuiHuaGame33--前拼后广--画画填色Game-mc

    com.MC.HuiHuaGame33--前拼后广--画画填色Game-mc

  8. 123457123456#0#-----com.ppGame.huaHua65--前拼后广--儿童填色-pp

    com.ppGame.huaHua65--前拼后广--儿童填色-pp

  9. 123457123456#0#-----com.twoapp.ErTongHuaHua01--前拼后广--儿童绘画填色游戏jiemei

    com.twoapp.ErTongHuaHua01----儿童绘画填色游戏jiemei

  10. 第七届蓝桥杯试题c/c++A组方格填数 回溯法

    方格填数如下的10个格子   +--+--+--+   |  |  |  |+--+--+--+--+|  |  |  |  |+--+--+--+--+|  |  |  |+--+--+--+(如果 ...

随机推荐

  1. WPF|黑暗模式的钱包支付仪表盘界面设计

    阅读目录 效果展示 准备 简单说明 + 源码 结尾(视频及源码仓库) 1. 效果展示 欣赏效果: 2. 准备 创建一个WPF工程,比如站长使用 .NET 7 创建名为 WalletPayment 的W ...

  2. [转帖]【P1】Jmeter 准备工作

    文章目录 一.Jmeter 介绍 1.1.Jmeter 有什么样功能 1.2.Jmeter 与 LoadRunner 比较 1.3.常用性能测试工具 1.4.性能测试工具如何选型 1.5.学习 Jme ...

  3. [转帖]KingbaseES V8R6 中walminer的使用

    https://www.cnblogs.com/kingbase/p/17315750.html 前言 walminer工具可以帮助dba挖掘wal日志中的内容,看到某时间对应数据库中的具体操作.例如 ...

  4. [转帖]5.2. 使用HINT

    ¶ 本章节包含以下内容: 概述 HINT的功能 HINT的使用 配置参数 示例 注意 5.2.1. 概述 ¶ KingbaseES使用的是基于成本的优化器.优化器会估计SQL语句的每个可能的执行计划的 ...

  5. [转帖]⭐万字长篇超详细的图解Tomcat中间件方方面面储备知识⭐

    https://developer.aliyun.com/article/885079?spm=a2c6h.24874632.expert-profile.321.7c46cfe9h5DxWK 202 ...

  6. OpenGauss3.1.0 单机版安装部署过程

    背景 由易到难 先进行单节点的设置 先说坑 openEuler2203 默认安装了python3.9 但是openGauss里面指代了3.6和3.7 /openGauss/install/om 注意在 ...

  7. 一次OOM事故的学习过程

    事故过程 周二下午得到消息, 希望帮忙分析dump文件. 告知dump大小为42G大小. 一般机器没这么大的内存进行处理. 建议现场上传到百度云盘, 然后我这边进行下载. 时间进度为: 11.57创建 ...

  8. Operating.System.Concepts.10th.Edition中文翻译

    <操作系统概念>是一本很好的书,主要介绍了操作系统的各个层面的概念,包含CPU调度,内存处理,文件系统等,目前已经出到第10版,是一本非常经典的书籍,从第1版至今被国内外众多高校选作教材, ...

  9. 谈JVM参数GC线程数ParallelGCThreads合理性设置

    作者:京东零售 刘乐 导读:本篇文章聚焦JVM参数GC线程数的合理配置,从ParallelGCThreads参数含义.参数设置,到参数实验以及修改意见进行解析. 1. ParallelGCThread ...

  10. 小程序字节转GBK及UTF8

    前段时间在Android原生搞的BLE扫码枪又要移植到小程序上来.本以为小程序不支持BLE的,结果一搜,还真支持-_-|| . 蓝牙部分问题不大,遇到的主要问题是,小程序环境如何对字符编码进行判断以及 ...