博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
矩阵和线性方程组
阅读量:7211 次
发布时间:2019-06-29

本文共 5913 字,大约阅读时间需要 19 分钟。

总结:满足下面这句话的条件,都可以考虑矩阵乘法+快速幂——把一个向量v变成另一个向量v',并且v'的每一个分量都是v的各个分量的线性组合。

 

1、UVa 10870, Recurrences

题意:给出递推关系f(n) = a1*f(n-1) + a2*f(n-2)....ad*f(n-d),给出d, n, m, a1, a2, ...ad, f(1), f(2)...f(n-d),求f(n) % m。

解法:矩阵乘法+快速幂。这是我第一次做矩阵乘法的题,由于是专题训练,一上来就构造成f(n) = G * F(n-1),只需要G = [a1, a2,...ad],F(n-1) = [f(n-1), f(n-2),...f(n-d)]T即可。

   但是,这样构造显然是不对的,我们要构造出的灯式形势应该是这样的(矩阵)F(n) = (d*d的矩阵)G * (矩阵)F(n-1),只有这样的形式(G为d*d),才能使用矩阵乘法快速幂。

   所以,F(n) = [f(n-d), f(n-d+1),...f(n-1)]T,

   G = [0   1        ]

          [    0    1          ]

      [...     ...    ]

      [                     0     1]                      

      [ad a(d-1)....    a2  a1] (d*d的矩阵)

   构造出来,这道题便得以解决。

tag:math, matrix

1 /* 2  * Author:  Plumrain 3  * Created Time:  2013-09-10 21:16 4  * File Name: math-UVa-10870.cpp 5  */ 6 #include
7 #include
8 #include
9 10 using namespace std;11 12 #define CLR(x) memset(x, 0, sizeof(x))13 #define out(x) cout<<#x<<":"<<(x)<
0){51 if (num & 1) 52 mtx_mul (ret, A, n);53 num >>= 1;54 mtx_mul (A, A, n);55 }56 57 for (int i = 0; i < n; ++ i)58 for (int j = 0; j < n; ++ j)59 A[i][j] = ret[i][j];60 }61 62 int gao (int m, int n)63 {64 matrix A;65 mtx_init (A, n);66 67 mtx_pow (A, m-n, n); 68 int ret = 0;69 for (int i = 0; i < n; ++ i)70 ret = (((A[n-1][i] * f[i+1]) % mod) + ret) % mod;71 if (ret < 0) ret += mod;72 return ret;73 }74 75 int main()76 {77 int n, m; 78 while (scanf ("%d%d%d", &n, &m, &mod) != EOF && n){79 for (int i = 1; i <= n; ++ i){80 scanf ("%d", &a[i]);81 a[i] %= mod;82 }83 for (int i = 1; i <= n; ++ i){84 scanf ("%d", &f[i]);85 f[i] %= mod;86 }87 88 if (m <= n) printf ("%d\n", f[m]);89 else printf ("%d\n", gao (m, n));90 }91 return 0;92 }
View Code

 

2、NEERC 2006, LA 3704, Cellular Automaton

题意:一个环上有n个点,标号依次为0,1...n-1。每次操作后,每个点的值都将变为,与它距离小于等于d的所有点在操作之前的值之和mod m的值。给定n, m, d, k和n个格子各自的值,求经过k次操作之后每个格子的值。

解法:

tag:math, circulant matrix,

1 /* 2  * Author:  Plumrain 3  * Created Time:  2013-09-13 12:59 4  * File Name: math-NEERC2006-LA3704.cpp 5  */ 6 #include
7 #include
8 #include
9 10 using namespace std;11 12 #define CLR(x) memset(x, 0, sizeof(x))13 14 const int N = 500;15 16 typedef long long int64;17 typedef int64 matrix[N+5];18 19 int n, mod, d, k;20 int64 a[N+5];21 int64 A[N+5];22 23 void mtx_mul(matrix& A, matrix B)24 {25 matrix ret;26 CLR (ret);27 for (int i = 0; i < n; ++ i)28 for (int j = 0, pos = i; j < n; ++ j, pos=(pos-1+n)%n)29 ret[i] = ((A[j] * B[pos]) % mod + ret[i]) % mod;30 31 for (int i = 0; i < n; ++ i)32 A[i] = ret[i];33 }34 35 void mtx_pow(matrix& A, int num)36 {37 if (num == 1) return;38 39 matrix ret;40 for (int i = 0; i < n; ++ i)41 ret[i] = A[i];42 -- num;43 44 while (num > 0){45 if (num & 1) mtx_mul (ret, A);46 num >>= 1;47 mtx_mul (A, A);48 }49 50 for (int i = 0; i < n; ++ i)51 A[i] = ret[i];52 }53 54 void gao()55 {56 CLR (A);57 int pos1 = 0, pos2 = 0;58 int cnt = 0;59 while (cnt <= d){60 A[pos1] = 1; A[pos2] = 1;61 62 ++ cnt;63 pos1 = (pos1+1) % n;64 pos2 = (pos2-1+n) % n;65 }66 67 mtx_pow(A, k);68 69 for (int i = 0; i < n; ++ i){70 int64 x = 0;71 for (int j = 0; j < n; ++ j)72 x = ((A[(j-i+n)%n]*a[j]) % mod + x) % mod;73 74 printf ("%lld", x);75 if (i != n-1) printf (" ");76 }77 printf ("\n");78 }79 80 int main()81 {82 while (scanf ("%d", &n) != EOF){ 83 scanf ("%d%d%d", &mod, &d, &k);84 for (int i = 0; i < n; ++ i)85 scanf ("%lld", &a[i]);86 87 gao ();88 }89 return 0;90 }
View Code

 

3、POJ 3070 Fibonacci

题意:对于Fibonacci数列,“0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …”,(F0 = 0)可以用矩阵的方法求得Fn。给n,求Fn。

解法:本来,如果直接说给n求Fn,这道题还是很有价值的。但是题目不仅仅是直接说了用矩阵求,甚至直接将给出如下图片:

这道题就直接按照这个图片写就好了.....

Ps:用矩阵求类似问题的构造方法,还有就是刘汝佳书上写的那种构造方法,那个是通用的。即本篇文章第一题。

tag:math, matrix, good

1 /* 2  * Author:  Plumrain 3  * Created Time:  2013-10-14 15:42 4  * File Name: math-POJ-3070.cpp 5  */ 6 #include
7 #include
8 #include
9 10 using namespace std;11 12 #define CLR(x) memset(x, 0, sizeof(x))13 const int mod = 10000;14 typedef int matrix[10][10];15 16 void mtx_mul(matrix& A, matrix B)17 {18 matrix ret; CLR (ret);19 for (int i = 0; i < 2; ++ i)20 for (int j = 0; j < 2; ++ j){21 ret[i][j] = 0;22 for (int k = 0; k < 2; ++ k)23 ret[i][j] = (A[i][k] * B[k][j] + ret[i][j]) % mod;24 }25 26 for (int i = 0; i < 2; ++ i)27 for (int j = 0; j < 2; ++ j)28 A[i][j] = ret[i][j];29 }30 31 void mtx_pow(matrix& A, int n)32 {33 -- n;34 matrix ret; CLR (ret);35 for (int i = 0; i < 2; ++ i)36 for (int j = 0; j < 2; ++ j)37 ret[i][j] = A[i][j];38 while (n > 0){39 if (n & 1) mtx_mul(ret, A);40 n >>= 1;41 mtx_mul(A, A);42 }43 for (int i = 0; i < 2; ++ i)44 for (int j = 0; j < 2; ++ j)45 A[i][j] = ret[i][j];46 }47 48 int main()49 {50 int n;51 while (scanf ("%d", &n) != EOF && n != -1){52 matrix A; CLR (A);53 A[0][0] = 1; A[0][1] = 1; A[1][0] = 1;54 if (n < 4){55 if (!n) printf ("0\n");56 if (n == 1 || n == 2) printf ("1\n");57 if (n == 3) printf ("2\n");58 continue;59 }60 mtx_pow(A, n);61 printf ("%d\n", A[0][1] % mod); 62 }63 return 0;64 }
View Code

 

 

 

 

    

 

 

转载于:https://www.cnblogs.com/plumrain/p/matrix.html

你可能感兴趣的文章
我曾经七次鄙视自己的灵魂 卡里.纪伯伦
查看>>
上传RNA-seq数据到NCBI GEO数据库
查看>>
3分钟快速presentation
查看>>
弹出无边框网页的Javscrpt代码
查看>>
C#代码中背后进行的值拷贝
查看>>
事件处理程序的执行上下文
查看>>
现代软件工程讲义 目录
查看>>
android 拨打电话与发送短信
查看>>
ORM内核原理解析之:延迟加载
查看>>
Oracle 默认表空间(default permanent tablespace) 说明
查看>>
jquery 遍历 TextBox 输入框求和,求平均值并判断输入内容是否为数字
查看>>
设计模式之十(外观模式)
查看>>
Dapper的语法应用
查看>>
easyui的validatebox重写自定义验证规则的几个实例
查看>>
ubuntu下定时任务的执行
查看>>
Effective C++ 条款44
查看>>
如何用消息系统避免分布式事务?
查看>>
Linux curl使用简单介绍 (转)
查看>>
Deep Learning(深度学习)学习笔记整理系列之(一)
查看>>
查看sqlserver被锁的表以及如何解锁
查看>>