算法核心:矩阵建模,矩阵的快速幂
大意:已知有n只猫咪,开始时每只猫咪有花生米0颗,先有一组操作:
由下面三个中的k个操作组成:
g i 给i只猫咪一颗花生米
e i 让第i只猫咪吃掉它拥有的所有花生米
s i j 将猫咪i与猫咪j的拥有的花生米交换
现将上述操作做m次后,问每只猫咪有多少颗花生米?
分析:
因m的数据范围较大,用矩阵连乘。
构建矩阵模型,peanut[N] = {0,0,。。。。0,1}:即前n个数为0,最后一个数取1
matrix[N][N],初始化条件下为单位矩阵,。。。
对猫咪进行操作转化为在对矩阵peanut进行操作,一组操作过程转化为矩阵matrix,那么m次操作,即对peanut*(matrix^m)
EXP:
input:
316
g1
g2
g2
s12
g3
e2
初始化下矩阵:peanut
0001即每只猫咪的花生米个数为0
初始化下matrix为单位矩阵
1000
0100
0010
0001
经过操作
g1
给1号1颗花生米,即在第一列的最后一行加1
1000
0100
0010
1001
g2
1000
0100
0010
1101
g2
1000
0100
0010
1201
s12
//即交换第1,2列
0100
1000
0010
2101
g3
0100
1000
0010
2111
e2
//将第2列全部置为0
0000
1000
0010
2011
最后peanut=peanut*matrix*matrix.....*matrix=peanut*(matrix^m)故可用矩阵快速求幂
peanut的前n个数即为每只猫咪拥有的花生米数
-----------------------------------------------------------------------
P.S:
再说下几个要注意的地方:
(1):要注意在矩阵相乘的时候判断一下相乘的两个元素是否为0,否则会超时.
(2):要用__int64,结果超出了int型.
CODE:
- /*矩阵乘法*/
- /*AC代码:172ms*/
- #include <iostream>
- #define MAXN 105
- struct mat
- {
- __int64 v[MAXN][MAXN];
- mat()
- {memset(v,0,sizeof(v));}
- };
- mat e,ans;//e为转换矩阵,ans为e^M
- int N,M,K;
- mat matrix_mul(mat p1,mat p2)//矩阵乘法
- {
- mat t;
- int i,j,k;
- for(i=0;i<=N;i++)
- for(j=0;j<=N;j++)
- if(p1.v[i][j])//优化,不然会TLE
- for(k=0;k<=N;k++)
- t.v[i][k]+=(p1.v[i][j]*p2.v[j][k]);
- return t;
- }
- mat matrix_mi(mat p,int k)//矩阵快速幂
- {
- mat t;
- for(int i=0;i<=N;i++) t.v[i][i]=1;
- while(k)
- {
- if(k&1)
- t=matrix_mul(t,p);
- k>>=1;
- p=matrix_mul(p,p);
- }
- return t;
- }
- void Init()
- {
- int i,x,y,t;
- char w[2];
- memset(e.v,0,sizeof(e.v));
- for(i=0;i<=N;i++)//初始化e为单位矩阵
- e.v[i][i]=1;
- while(K--)
- {
- scanf("%s",w);
- if(w[0]=='g')//给一个
- {
- scanf("%d",&x);
- x--;//注意
- e.v[N][x]++;
- }
- else if(w[0]=='s')
- {
- scanf("%d%d",&x,&y);
- x--;y--;
- if(x!=y)
- {
- for(i=0;i<=N;i++)
- {t=e.v[i][x];e.v[i][x]=e.v[i][y];e.v[i][y]=t;}
- }
- }
- else
- {
- scanf("%d",&x);
- x--;
- for(i=0;i<=N;i++)
- e.v[i][x]=0;
- }
- }
- }
- int main()
- {
- int i,j;
- while(scanf("%d%d%d",&N,&M,&K)!=EOF)
- {
- if(N==0&&M==0&&K==0) break;
- Init();
- /*
- for(i=0;i<=N;i++)
- {
- for(j=0;j<=N;j++)
- printf("%d ",e.v[i][j]);
- printf("\n");
- }
- */
- ans=matrix_mi(e,M);
- int i;
- for(i=0;i<N;i++)//输出前N个即可
- printf("%I64d ",ans.v[N][i]);
- printf("\n");
- }
- return 0;
- }
相关推荐
例如,在解决斐波那契数列、线性递推关系、矩阵快速幂等问题时,都能看到它的身影。熟练掌握快速幂算法,不仅能够提升代码性能,还能在解决复杂问题时提供思路。 通过阅读“快速幂算法详解:高效计算大数幂的利器....
在许多应用中,如数据处理、控制系统和物理建模,了解矩阵的特征值和特征向量是至关重要的。 幂法是求矩阵最大特征值的一种简单且有效的迭代方法。其基本思想是,选择一个与矩阵的某一个特征向量接近的初始向量x0,...
尽管快速幂算法与旋翼飞行器控制之间的直接联系并不明显,但其在数学建模和优化计算方面的作用可以间接地支持旋翼飞行器的控制系统设计。下面将详细介绍快速幂算法,并探讨其如何应用于旋翼飞行器控制领域。 #### ...
MATLAB 数学建模基础入门教程 本资源提供了 MATLAB 数学...本资源提供了 MATLAB 数学建模基础入门教程,涵盖了 MATLAB 的基础知识、函数定义、数组操作、矩阵运算等内容,旨在帮助用户快速掌握 MATLAB 的使用和应用。
**矩阵加速**是一种通过运用矩阵运算技巧(尤其是矩阵快速幂)来优化某些基于线性的问题处理效率的技术。该技术通常应用于那些可以通过线性递推关系进行建模的问题场景之中。 #### 二、矩阵加速的应用背景 在...
5. 利用矩阵乘法求斐波那契数列的第n项模p的值,可以通过构建特定的矩阵模型,如矩阵Fibonacci矩阵,通过矩阵快速幂计算出结果。 这些题目展示了矩阵乘法在处理几何变换、动态规划、序列操作等复杂问题时的高效性和...
通过连续多次自乘,可以快速计算出矩阵的幂次,对于幂为整数的情况,可以利用平方和快速幂算法提高效率。 行列式是矩阵运算中的另一个关键概念,它反映了矩阵的某些特性。工具提供了计算行列式的方法,这对于判断...
在MATLAB中,矩阵是基本的数据结构,广泛用于数值计算、数据分析和科学建模。本文主要探讨矩阵的创建、引用、运算以及特殊矩阵和矩阵变换。 1. 冒号表达式: 冒号(:)是MATLAB中创建序列的重要工具。例如,`e1:e2:...
快速幂取模算法在程序设计竞赛和数学建模中被广泛应用,如计算大整数的阶乘、求解斐波那契数列、矩阵快速幂等。理解并掌握快速幂取模算法能够显著提高处理这类问题的效率,对于参加算法竞赛或解决相关问题的程序员来...
这些代码可以帮助学习者深入理解算法细节,通过实际操作加深对理论知识的理解,并能快速应用于新的建模问题。 总结来说,数学建模算法与程序是解决实际问题的强大工具,无论是线性还是非线性分析,都有其独特的应用...
例如,在线性代数部分,可能会涉及矩阵运算、特征值计算、解线性方程组等,这些都可以通过MATLAB的矩阵运算功能来高效实现;在微积分部分,可能涵盖微分方程的数值解法,如欧拉方法、龙格-库塔方法等,MATLAB的ode...
通过对数据的高效处理,Excel能帮助建模者快速构建和验证模型,从而在实际问题解决中发挥关键作用。因此,对于数学建模者来说,熟练掌握Excel的各种功能和应用技巧,无疑将提升建模工作的效率和精度。
3. **矩阵函数**:如指数矩阵、对数矩阵、幂次矩阵、求逆矩阵等,这些高级运算在解决非线性问题时尤为重要。 4. **矩阵属性查询**:检查矩阵的大小、秩、行列式、特征值等,这些信息对于系统分析和稳定性评估至关...
7. **矩阵函数**:Matlab还提供了如指数函数`expm()`、对数函数`logm()`、幂函数`powerm()`等对矩阵操作的函数,这些在处理矩阵运算时非常方便。 通过学习和掌握这些Matlab在线性代数中的应用,数学建模者能够更...
此外,MATLAB 的运算符包括加减乘除(`+`, `-`, `*`, `/`),数组乘法和除法(`.*`, `./`),矩阵乘法和幂运算(`.*`, `.^`),以及左除、右除(`\`, `/`)等。 在数学函数方面,MATLAB 提供了各种基本的数学和三角...
在MATLAB开发中,矩阵表达式是至关重要的概念,它涉及到数学建模、数值计算以及数据分析等多个领域。本文将深入探讨如何使用MATLAB处理矩阵表达式,特别是通过Leja插值来计算`expm(ta)*b`,而无需直接求解矩阵指数。...
现在我们将详细讨论如何用递归、迭代和矩阵快速幂三种方法来求解斐波那契数列的和,并分析它们的时间复杂度。 1. **递归实现** 递归是最直观的方式来表示斐波那契数列,但也是效率最低的方法。递归函数通常定义为:...
4. `p=p+S^i`:这里使用矩阵乘法的幂运算,S^i表示S自身与其相乘i-1次,这样就包含了所有长度为i的路径信息。将这个结果累加到p上,表示从任一状态出发,经过最多i步可以到达的状态集合。 5. `p(p~=0)=1`:将p中非零...
此外,还有`LOG`、`LOG10`用于计算对数,`MINVERSE`用于求逆矩阵,`MMULT`执行矩阵乘法,`MOD`计算两数相除的余数,`RAND`和`RANDBETWEEN`则生成随机数,`ROUND`系列函数用于数值的四舍五入。 2. **数据组织与管理*...