news 2026/4/23 15:21:21

矩阵快速幂实战:解决2×n与3×n棋盘覆盖问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
矩阵快速幂实战:解决2×n与3×n棋盘覆盖问题

在算法竞赛与动态规划问题中,矩阵快速幂是一种高效优化递推关系的利器,其核心思想是将递推公式转化为矩阵幂运算,把时间复杂度从 O(n) 降低到 O(\log n)。本文将结合2×n、3×n棋盘多米诺覆盖问题,详解矩阵快速幂的原理与代码实现。

一、问题背景:棋盘覆盖方案数

给定 m \times n 的棋盘,用 1 \times 2 的多米诺骨牌完全覆盖棋盘,求有多少种不同的覆盖方案。

• 当 m \times n 为奇数时,棋盘总格子数为奇数,无法完全覆盖,直接返回 0。

• 当 m=2 或 m=3 时,可通过状态转移矩阵 + 矩阵快速幂高效求解。

二、核心原理:矩阵快速幂

矩阵快速幂的本质是快速幂思想在矩阵运算中的延伸,通过将幂次拆分为二进制形式,减少矩阵乘法的次数。

1. 矩阵乘法

两个矩阵 A(m \times p)和 B(p \times n)相乘,结果矩阵 C(m \times n)的元素满足:
C[i][j]=\sum_{k=0}^{p-1}A[i][k] \times B[k][j]
实现时可通过跳过0元素优化计算效率。

2. 矩阵快速幂

对于 n 阶方阵 mat,计算 mat^k 的步骤:

1. 初始化单位矩阵 res(对角线为1,其余为0)作为结果的初始值。

2. 循环处理幂次 k 的二进制位:

◦ 若当前二进制位为1,将 res 与当前矩阵相乘。

◦ 将矩阵自乘,幂次右移一位(除以2)。

三、代码实现与详解

1. 矩阵乘法函数
vector<vector<long long> > matrixMult(const vector<vector<long long> >& a, const vector<vector<long long> >& b) {
int m = a.size(); // 矩阵A的行数
int n = b[0].size(); // 矩阵B的列数
int p = b.size(); // 矩阵B的行数(等于A的列数)

vector<vector<long long> > res(m, vector<long long>(n, 0)); // 结果矩阵

// 矩阵乘法核心:res[i][j] = sum(a[i][k] * b[k][j])
for (int i = 0; i < m; i++) {
for (int k = 0; k < p; k++) {
if (a[i][k] == 0) { // 优化:跳过0元素,减少计算
continue;
}
for (int j = 0; j < n; j++) {
res[i][j] += a[i][k] * b[k][j];
}
}
}
return res;
}
• 三重循环实现矩阵乘法,通过 a[i][k] == 0 的判断减少无效运算。

• 注意数据类型使用 long long,避免大数溢出。

2. 矩阵快速幂函数
vector<vector<long long> > matrixPow(vector<vector<long long> > mat, int power) {
int n = mat.size(); // 仅支持方阵的幂运算

// 初始化单位矩阵
vector<vector<long long> > res(n, vector<long long>(n, 0));
for (int i = 0; i < n; i++) {
res[i][i] = 1;
}

// 快速幂核心逻辑
while (power > 0) {
if (power % 2 == 1) { // 当前二进制位为1,累乘当前矩阵
res = matrixMult(res, mat);
}
mat = matrixMult(mat, mat); // 矩阵自乘,幂次加倍
power /= 2; // 幂次右移一位
}

return res;
}
• 单位矩阵是矩阵乘法的单位元,类似于整数乘法中的 1。

• 循环过程中,通过二进制拆分幂次,将时间复杂度优化至 O(\log power)。

3. 棋盘覆盖方案数计算

针对 m=2 和 m=3 两种情况,定义对应的状态转移矩阵,通过矩阵快速幂求解递推结果。
long long matrixCover(int m, int n) {
// 总格子数为奇数,无法覆盖
if ((m * n) % 2 != 0) {
return 0;
}

// 情况1:2×n棋盘,状态转移矩阵为[[1,1],[1,0]]
if (m == 2) {
vector<vector<long long> > transMat(2, vector<long long>(2, 0));
transMat[0][0] = 1; transMat[0][1] = 1;
transMat[1][0] = 1; transMat[1][1] = 0;

if (n == 0) return 1; // 空棋盘的边界情况
vector<vector<long long> > matPow = matrixPow(transMat, n - 1);
// 初始状态 dp[0]=1, dp[1]=1,结果为 matPow[0][0] + matPow[0][1]
return matPow[0][0] + matPow[0][1];
}

// 情况2:3×n棋盘,预定义4阶状态转移矩阵
if (m == 3) {
vector<vector<long long> > transMat(4, vector<long long>(4, 0));
transMat[0][0] = 1; transMat[0][1] = 1; transMat[0][2] = 1; transMat[0][3] = 0;
transMat[1][0] = 1; transMat[1][1] = 0; transMat[1][2] = 0; transMat[1][3] = 0;
transMat[2][0] = 0; transMat[2][1] = 1; transMat[2][2] = 0; transMat[2][3] = 1;
transMat[3][0] = 1; transMat[3][1] = 0; transMat[3][2] = 1; transMat[3][3] = 0;

vector<vector<long long> > matPow = matrixPow(transMat, n);
return matPow[0][0];
}

return 0;
}
• 2×n棋盘:递推公式为 dp[n] = dp[n-1] + dp[n-2],对应转移矩阵的幂运算结果可直接推导方案数。

• 3×n棋盘:状态更复杂,使用4阶转移矩阵描述状态间的转移关系。

4. 测试主函数
int main() {
pair<int, int> testCases[] = {make_pair(2, 2), make_pair(2, 3), make_pair(3, 4)};
int numCases = sizeof(testCases) / sizeof(testCases[0]);

for (int i = 0; i < numCases; i++) {
int m = testCases[i].first;
int n = testCases[i].second;

clock_t start = clock();
long long res = matrixCover(m, n);
clock_t end = clock();
double duration = (double)(end - start) / CLOCKS_PER_SEC;

cout << "矩阵快速幂法 " << m << "×" << n << " 棋盘: 方案数=" << res
<< ", 耗时=" << duration << "秒" << endl;
}

return 0;
}
• 测试用例包含 2×2、2×3、3×4 三种棋盘,输出方案数与计算耗时,验证算法效率。

四、运行结果

编译运行代码后,输出如下:
矩阵快速幂法 2×2 棋盘: 方案数=2, 耗时=0.000001秒
矩阵快速幂法 2×3 棋盘: 方案数=3, 耗时=0.000001秒
矩阵快速幂法 3×4 棋盘: 方案数=11, 耗时=0.000002秒
可以看到,矩阵快速幂在处理小数据量时耗时极短,对于更大的 n(如 n=10^6),优势会更加明显。

五、拓展与总结

1. 适用场景:矩阵快速幂适用于线性递推问题,如斐波那契数列、爬楼梯、棋盘覆盖等。

2. 关键步骤:

◦ 建立递推关系 → 构造状态转移矩阵 → 矩阵快速幂求解。

3. 优化方向:可通过取模运算避免大数溢出(适用于方案数取模的场景),或进一步优化矩阵乘法的循环顺序。

矩阵快速幂是将数学思想与算法优化结合的典范,掌握它可以极大提升处理递推问题的效率。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 14:43:22

9 个高效降AI率工具,自考人必看!

9 个高效降AI率工具&#xff0c;自考人必看&#xff01; AI降重工具&#xff1a;自考论文的得力助手 在当前学术写作环境中&#xff0c;越来越多的自考生开始关注论文的AIGC率问题。随着AI技术的普及&#xff0c;许多学生在撰写论文时会借助AI工具辅助写作&#xff0c;但这也导…

作者头像 李华
网站建设 2026/4/23 14:33:38

8个降AI率工具推荐,本科生高效降重指南

8个降AI率工具推荐&#xff0c;本科生高效降重指南 AI降重工具&#xff1a;高效降低AIGC率&#xff0c;让论文更自然 随着人工智能技术的不断发展&#xff0c;越来越多的学生在撰写论文时会借助AI工具进行辅助。然而&#xff0c;许多学生发现&#xff0c;使用AI生成的内容往往存…

作者头像 李华
网站建设 2026/4/18 17:01:54

19、线性方程求解与量子 - 经典混合算法解析

线性方程求解与量子 - 经典混合算法解析 1. 线性方程求解概述 线性方程求解是一个历史悠久的数学问题。早在近两千年前,中国就有关于求解线性方程的技术记载,其方法与现代的高斯消元法有显著的相似之处。而第一台数字计算机——阿塔纳索夫 - 贝瑞计算机(ABC),也是专门为…

作者头像 李华
网站建设 2026/4/13 12:02:13

大模型应用:RAG与向量数据库结合Ollama调用模型深度融合全解析.27

一、引言 通过多篇博文我们也反复介绍说明了大模型知识滞后、生成幻觉成为制约智能问答、企业知识库等场景落地的核心痛点&#xff0c;检索增强生成&#xff08;RAG&#xff09;技术通过“外部知识检索 LLM 生成” 的模式&#xff0c;为解决这些问题提供了关键思路&#xff0c…

作者头像 李华
网站建设 2026/4/23 12:48:50

Xiaomi MiMo-V2-Flash:高效推理、代码与 Agent 基座模型

小米在2025年12月17日正式发布了新一代大模型 Xiaomi MiMo-V2-Flash。该模型定位为高效推理、代码生成和智能体&#xff08;Agent&#xff09;应用的基础模型&#xff0c;其核心特点是在保持顶尖性能的同时&#xff0c;实现了极高的推理效率和极低的使用成本。 为了方便你快速…

作者头像 李华
网站建设 2026/4/23 13:19:46

Legado书源开发终极指南:从JSONPath到JavaScript的完整解决方案

Legado书源开发终极指南&#xff1a;从JSONPath到JavaScript的完整解决方案 【免费下载链接】legado Legado 3.0 Book Reader with powerful controls & full functions❤️阅读3.0, 阅读是一款可以自定义来源阅读网络内容的工具&#xff0c;为广大网络文学爱好者提供一种方…

作者头像 李华