矩阵乘法和快速幂的一些优化和剪枝
矩阵相乘
一般会用O(n^3)的方法。。。配合剪枝【添条件,设门槛。。。】
//O(n^3)算法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
#define LL __int64
#define MOD 1000
typedef struct MATRIX
{ int mat[50][50];
}MATRIX; MATRIX mat_multiply (MATRIX a,MATRIX b,int n)
{ MATRIX c; //c[i][j]= Σ a[i][k]*b[k][j] memset(c.mat,0,sizeof(c.mat));
/* for(int i=0;i<n;i++) //a矩阵一行一行往下 for(int j=0;j<n;j++) //b矩阵一列一列往右 for(int k=0;k<n;k++) //使a矩阵 第i行第k个元素 乘以 b矩阵 第j列第k个元素 if(a[i][k] && b[k][j]) //剪枝(添条件,设门槛),提高效率,有一个是0,相乘肯定是0 c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
*/ //上面也是可以的,但是下面的剪枝更好一些,效率更高一些,但是运算顺序有点难想通,,,
//上面就是C[i][j]一次就求出来,下面就是每次c[i][j]求出一项【就是上面红体字,每次各求一列】 for(int k=0;k<n;k++) //这个可以写到前面来, for(int i=0;i<n;i++) if(a.mat[i][k]) //剪枝:如果a.mat[i][k]是0,就不执行了 for(int j=0;j<n;j++) if(b.mat[k][j]) //剪枝:如果b.mat[i][k]是0,就不执行了 { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; if(c.mat[i][j]>=MOD) //这个看实际需求,要不要取模 c.mat[i][j]%=MOD; //取模的复杂度比较高,所以尽量减少去模运算,添加条件,只有当大于等于MOD的时候才取余 } return c;
} int main()<span style="white-space:pre"> </span>//这个只是用来测试用的。。。
{ int n; MATRIX A,B,C; memset(A.mat,0,sizeof(A.mat)); memset(B.mat,0,sizeof(B.mat)); memset(C.mat,0,sizeof(C.mat)); scanf("%d",&n); //矩阵规模,这里是方阵,行数等于列数 for(int i=0;i<n;i++) //初始化A矩阵 for(int j=0;j<n;j++) scanf("%d",&A.mat[i][j]); for(int i=0;i<n;i++) //初始化B矩阵 for(int j=0;j<n;j++) scanf("%d",&B.mat[i][j]); C=mat_multiply (A,B,n); for(int i=0;i<n;i++) //打印C矩阵 { for(int j=0;j<n;j++) printf("%3d",C.mat[i][j]); printf("\n"); } return 0;
}
矩阵快速幂
//矩阵快速幂
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
#define LL __int64
#define MOD 1000
typedef struct MATRIX
{ int mat[50][50];
}MATRIX; MATRIX mat_multiply (MATRIX a,MATRIX b,int n)
{ MATRIX c; //c[i][j]= Σ a[i][k]*b[k][j] memset(c.mat,0,sizeof(c.mat));
/* for(int i=0;i<n;i++) //a矩阵一行一行往下 for(int j=0;j<n;j++) //b矩阵一列一列往右 for(int k=0;k<n;k++) //使a矩阵 第i行第k个元素 乘以 b矩阵 第j列第k个元素 if(a[i][k] && b[k][j]) //剪枝(添条件,设门槛),提高效率,有一个是0,相乘肯定是0 c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
*/ //上面也是可以的,但是下面的剪枝更好一些,效率更高一些,但是运算顺序有点难想通,,,
//上面就是C[i][j]一次就求出来,下面就是每次c[i][j]求出一项【就是上面红体字,每次各求一列】 for(int k=0;k<n;k++) //这个可以写到前面来, for(int i=0;i<n;i++) if(a.mat[i][k]) //剪枝:如果a.mat[i][k]是0,就不执行了 for(int j=0;j<n;j++) if(b.mat[k][j]) //剪枝:如果b.mat[i][k]是0,就不执行了 { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; if(c.mat[i][j]>=MOD) //这个看实际需求,要不要取模 c.mat[i][j]%=MOD; //取模的复杂度比较高,所以尽量减少去模运算,添加条件,只有当大于等于MOD的时候才取余 } return c;
} MATRIX mat_quick_index(MATRIX a,int N,int n)
{ MATRIX E; //单位矩阵,就像数值快速幂里,把代表乘积的变量初始化为1 // memset(E.mat,0,sizeof(E.mat)); //置零,单位矩阵除了主对角线都是1,其他都是0
// for(int i=0;i<n;i++) //初始化单位矩阵【就是主对角线全是1】
// E.mat[i][i]=1; for(int i=0;i<n;i++) for(int j=0;j<n;j++) E.mat[i][j]=(i==j); //酷炫*炸天的初始化!!! while(N>0) { if(N & 1) E=mat_multiply(E,a,n); N>>=1; a=mat_multiply(a,a,n); } return E;
} int main()
{ int n,N; //n为矩阵(方阵)规模,几行,N为指数 MATRIX A,C; memset(A.mat,0,sizeof(A.mat)); memset(C.mat,0,sizeof(C.mat)); scanf("%d",&n); //矩阵规模,这里是方阵,行数等于列数 for(int i=0;i<n;i++) //初始化A矩阵 for(int j=0;j<n;j++) scanf("%d",&A.mat[i][j]); scanf("%d",&N); C=mat_quick_index(A,N,n); for(int i=0;i<n;i++) //打印C矩阵 { for(int j=0;j<n;j++) printf("%3d",C.mat[i][j]); printf("\n"); } return 0;
}
矩阵乘法和快速幂的一些优化和剪枝相关推荐
- 算法提高课-数学知识-矩阵乘法-AcWing 1303. 斐波那契前 n 项和:矩阵乘法,快速幂,线性代数
题目分析 来源:acwing 分析: 先利用矩阵运算的性质将通项公式变成幂次形式,然后用快速幂的方法求解第 n项. 斐波那契数列的递推公式:f1=f2=1,fn=fn−2+fn−1(n≥3)f_1 = ...
- 矩阵快速幂以及其优化【华东交大课程】
矩阵快速幂以及其优化[华东交大课程] 快速幂基础:C++快速幂_Kicamon的博客-CSDN博客 矩阵快速幂就是在快速幂的基础上结合矩阵运算的用法,其用途较为广泛,可以很大程度上优化代码. 一.矩阵 ...
- 2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)- 分组(矩阵快速幂套NTT优化dp)
题目链接:点击查看 题目大意:给出 nnn 个连续的小球,每次可以选择单独的一个或者相邻的两个小球分成一组,允许有剩余的小球,问恰好分成 k∈{1,2,3,⋯,m}k\in\{1,2,3,\cdots ...
- 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)
先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...
- 2021HDU多校8 - 7057 Buying Snacks(矩阵快速幂套NTT优化dp)
题目链接:点击查看 题目大意:给出 nnn 种糖果,每种糖果有大小包装之分,有三种购买方案,价钱分别如下: 单独购买一个小的,花费一块钱 单独购买一个大的,花费两块钱 ∀i>1\forall i ...
- 矩阵的乘法和快速幂的一些理解(适用初学者)
矩阵是线性代数的知识...后悔没好好学了... 第一部分:矩阵的基础知识 1.结合性 (AB)C=A(BC). 2.对加法的分配性 (A+B)C=AC+BC,C(A+B)=CA+CB . 3.对数乘的 ...
- (组合数求模=乘法逆元+快速幂) Problem Makes Problem
题目: As I am fond of making easier problems, I discovered a problem. Actually, the problem is 'how ca ...
- HDU 4365 正方形格子涂色中心对称轴对称的涂法有多少种-思维-(矩阵坐标关系快速幂取模)
题意:n*n的格子,涂色,有k种颜料,必须满足旋转任意个90度和翻转之后图片的样子不变,现在已经有m个格子涂过色了,问还有多少种涂法满足上述条件. 分析: 满足上述对称条件,那么涂色的种类问题我们可以 ...
- [矩阵乘法/快速幂专题]Arc of Dream,Recursive sequence,233 Matrix,Training little cats
矩阵快速幂习题 复习矩阵乘法及快速幂模板 乘法模板 快速幂模板 T1:Arc of Dream 题目 题解 code T2:Recursive sequence 题目 题解 code T3:233 M ...
最新文章
- 【温故知新】CSS学习笔记(选择器)
- poj 3126 BFS
- HTML课程表应用,可在PC和Android运行
- 【论文写作】网上选课系统中模块设计如何写
- Rhino(js的java实现组件)
- BZOJ4152 AMPPZ2014 The Captain 【最短路】【贪心】*
- 推荐使用一个modbus调试助手
- android原生桌面,谷歌官方出品的安卓原生桌面App 轻松干掉你手机上臃肿的的桌面!...
- 三、大数据时代下的SQL Server第三方负载均衡方案----Moebius测试
- 【转】高手速成android开源项目【View篇】
- 数字化转型中基于交付价值数据治理的6大原则
- 脉脉热帖:学历、履历双造假,拿了抖音Offer
- 实战玩客云刷armbian及共享打印机教程
- dnf剑魂buff等级上限_DNF:剑魂职业改版加强,超一线剑魂职业如何技能加点?...
- 埃森哲杯上海大学春季赛暨金马五校赛题解汇总
- Java软件工程师[初级测试题]
- webpack Vue热加载配置好的确不行解决方法,限于webstorm编辑
- 回车换行问题0x0D和0x0A
- 重写confirm,alert
- 软件生命周期管理(ALM)
热门文章
- vue 项目抛出警告
- m函数与m文件的命名
- 爬虫之验证码IP攻防心得——小总结
- HDU 5908 Abelian Period 暴力
- C#可用的日出日落时间类
- 系列博文-Three.js入门指南(张雯莉)-静态demo和three.js功能概览
- Android Service与Runnable整合并用
- PHP Parse error: parse error, unexpected T_OBJECT_OPERATOR
- 深度之眼课程打卡-python入门05
- 单核工作法13:永不拖延(上)