news 2026/2/10 7:11:50

矩阵快速幂实战:解决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/2/5 10:13:41

9 个降AI率工具,专科生必备!

9 个降AI率工具&#xff0c;专科生必备&#xff01; AI降重工具&#xff1a;专科生论文写作的得力助手 随着人工智能技术的不断发展&#xff0c;越来越多的学术写作开始借助AI工具完成。然而&#xff0c;随之而来的AIGC率过高、查重率超标等问题也困扰着众多学生&#xff0c;尤…

作者头像 李华
网站建设 2026/2/9 18:03:39

python 环境问题

根据您提供的信息&#xff0c;问题可能出现在Python环境上。在PyCharm中可以运行&#xff0c;但换个文件夹&#xff08;即使用命令行运行&#xff09;就不行&#xff0c;这通常是因为两个环境使用的Python解释器或包不同。可能的原因和解决方案&#xff1a;检查Python环境&…

作者头像 李华
网站建设 2026/2/5 9:18:58

20、量子 - 经典混合算法与量子纠错技术解析

量子 - 经典混合算法与量子纠错技术解析 1. 量子近似优化算法(QAOA) 量子近似优化算法(QAOA)是一种典型的NISQ时代算法,能够在多项式时间内为组合优化问题提供近似解。它最初由Farhi等人提出,被视为变分量子本征求解器(VQE)的一个特例,也与量子绝热算法相关。 1.1 …

作者头像 李华
网站建设 2026/2/7 1:08:48

Lottie-web智能文档生成方案:让团队协作效率倍增的实用指南

Lottie-web智能文档生成方案&#xff1a;让团队协作效率倍增的实用指南 【免费下载链接】lottie-web 项目地址: https://gitcode.com/gh_mirrors/lot/lottie-web 还在为项目文档维护而头疼吗&#xff1f;每次代码更新后&#xff0c;手动同步文档不仅耗时耗力&#xff0…

作者头像 李华
网站建设 2026/2/10 4:07:26

VonaJS 5.0.242 实现了文件级别精确 HMR

VonaJS 5.0.242实现的文件级别精确HMR&#xff08;热模块替换&#xff09;&#xff0c;是一项旨在显著提升大型Node.js项目开发体验的核心特性。核心原理&#xff1a;与项目级HMR的对比它的核心创新在于将HMR的粒度从“整个项目”精确到了“单个文件”。为了让你快速理解其进步…

作者头像 李华