矩阵的相关性质再回顾

对于一个矩阵

  1. 满足结合律
  2. 满足乘法对于加法的分配率
  3. 但是不满足交换律!

对于特殊一点的矩阵来说:

把最左边还有最右面的看成一个数组。。

矩阵加速大法:

因为矩阵满足结合律,所以可以使用快速幂来进行计算。
规律总结:
矩阵加速设计到两个东西:

  • 状态矩阵
  • 转移矩阵
  1. 可以抽象出一个一维向量,在每一次递推就变化一次;
  2. 状态转移方程不发生变化;
  3. 状态转移过程中,一定是线性的(加减,乘以系数)
  4. 注意:状态矩阵需要尽可能短,转移次数可以比较大。

时间复杂度是

N

3

l

o

g

N

N^3logN

N3logN.

ACWing205. 斐波那契



要注意取模

代码

#include <bits/stdc++.h>
using namespace std;
const int len = 2;
const int mod = 10000;
void mulself(int a[2][2])
{
int c[2][2];
memset(c, 0, sizeof(c));
for(int i = 0; i < len; i++ )
for(int j = 0; j < len; j++)
for(int k = 0; k < len; k++)
c[i][j] = (c[i][j]+(long long)a[i][k] * a[k][j])%mod;
memcpy(a, c, sizeof(c));
}
void mul(int a[2][2], int f[2])
{
int c[2];
memset(c, 0, sizeof(c));
for(int j = 0; j < len; j++)
for(int k = 0; k < len; k++)
c[j] = (c[j] + (long long)f[k] * a[k][j])%mod;
memcpy(f, c, sizeof(c));
}
void solve(int n)
{
int a[2][2] = {{0, 1}, {1, 1}};
int f[2] = {0, 1};
for(; n; n >>= 1 )
{
if(n&1) mul(a, f);
mulself(a);
}
printf("%d\n", f[0]);
}
int main()
{
int n;
while((scanf("%d", &n)||1) && n != -1) solve(n);
return 0;
}

ACWing206. 石头游戏


解题思路:

感受:

太恶心了,一百多行代码,debug了一下午

代码


//在这个程序中所有的数组全部从1开始计数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,t,act;
char op[20][20];//表示操作
ll oplen[20];
ll mp[70];//表示单元格映射的操作数字
ll matrix[70][70][70];
ll p;//p表示状态矩阵的从 0 到 p;
inline ll num(ll x, ll y)
{
if(x==0 && y==0) return 0;
return (x-1)*m + y;
}
void read_op_and_mp()
{
char buf[12];
for(int i = 1; i <= n; i++)
{
scanf("%s", buf+1);
for(int j = 1; j <= m; j++)
{
mp[num(i, j)] = buf[j]-'0'+1;
}
}
for(int i = 1; i <= act; i++)
{
scanf("%s", op[i]+1);
oplen[i] = strlen(op[i]+1);
}
}
void mulself(ll a[70][70])//
{
ll c[70][70];
memset(c, 0, sizeof(c));
for(int i = 0; i<= p; i++)
for(int j = 0; j <= p; j++)
for(int k = 0; k <= p; k++)
c[i][j] += a[i][k] * a[k][j];
memcpy(a, c, sizeof(c));
}
void mul(ll f[], ll a[70][70])
{
ll c[70];
memset(c, 0, sizeof(c));
for(int j = 0; j <= p; j++)
for(int k = 0; k <= p; k++)
{
c[j] += f[k] * a[k][j];
}
memcpy(f, c, sizeof(c));//sizeof不能是f因为f是指针。
}
void make_matrix()
{
ll tmp[70][70];
for(int i = 0; i <= p; i++) matrix[0][i][i] = 1;//设置为单位矩阵
for(int tt = 1; tt <= 60; tt++)
{
memset(tmp, 0, sizeof(tmp));
tmp[0][0] = 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
char ch = op[mp[num(i, j)]][(tt-1)%oplen[mp[num(i, j)]]+1];
if('0' <= ch && ch <= '9')
{
tmp[num(0, 0)][num(i, j)] = ch-'0';
tmp[num(i, j)][num(i, j)] = 1;
}
else if(ch=='N')
{
if(i > 1) tmp[num(i, j)][num(i-1, j)] = 1;
}
else if(ch=='W')
{
if(j > 1) tmp[num(i, j)][num(i, j-1)] = 1;
}
else if(ch=='S')
{
if(i < n) tmp[num(i, j)][num(i+1, j)] = 1;
}
else if(ch=='E')
{
if(j < m) tmp[num(i, j)][num(i, j+1)] = 1;
}
}
for(int i = 0; i <= p; i++)
for(int j = 0; j <= p; j++)
for(int k = 0; k <= p; k++)
{
matrix[tt][i][j] += matrix[tt-1][i][k] * tmp[k][j];
}
}
}
ll solve()
{
ll ret = 0;
ll f[70] = {0};
f[0] = 1;
ll a[70][70];
make_matrix();
memcpy(a, matrix[60], sizeof(a));
ll xx = t / 60;
for(; xx; xx >>= 1)
{
if(xx&1) mul(f, a);
mulself(a);
}
mul(f, matrix[t%60]);
for(int i = 1; i <= p; i++) ret = max(ret, f[i]);
return ret;
}
int main()
{
cin >> n >> m >> t >> act;
read_op_and_mp();
p = m * n;
ll ans = solve();
cout << ans << endl;
return 0;
}

算法竞赛进阶指南0x34矩阵乘法的更多相关文章

  1. 算法竞赛进阶指南 0x00 基本算法

    放在原来这个地方不太方便,影响阅读体验.为了读者能更好的刷题,另起一篇随笔. 0x00 基本算法 0x01 位运算 [题目][64位整数乘法] 知识点:快速幂思想的灵活运用 [题目][最短Hamilt ...

  2. 算法竞赛进阶指南--快速幂,求a^b mod p

    // 快速幂,求a^b mod p int power(int a, int b, int p) { int ans = 1; for (; b; b >>= 1) { if (b &am ...

  3. 《算法竞赛进阶指南》0x10 基本数据结构 Hash

    Hash的基本知识 字符串hash算法将字符串看成p进制数字,再将结果mod q例如:abcabcdefg 将字母转换位数字(1231234567)=(1*p9+2*p8+3*p7+1*p6+2*p5 ...

  4. 《算法竞赛进阶指南》1.4Hash

    137. 雪花雪花雪花 有N片雪花,每片雪花由六个角组成,每个角都有长度. 第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,-,ai,6. 因为雪花的形状是封闭的环形,所以从任何一 ...

  5. bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)算法竞赛进阶指南

    题目描述 原题连接 Y岛风景美丽宜人,气候温和,物产丰富. Y岛上有N个城市(编号\(1,2,-,N\)),有\(N-1\)条城市间的道路连接着它们. 每一条道路都连接某两个城市. 幸运的是,小可可通 ...

  6. POJ1639 算法竞赛进阶指南 野餐规划

    题目描述 原题链接 一群小丑演员,以其出色的柔术表演,可以无限量的钻进同一辆汽车中,而闻名世界. 现在他们想要去公园玩耍,但是他们的经费非常紧缺. 他们将乘车前往公园,为了减少花费,他们决定选择一种合 ...

  7. 算法竞赛进阶指南0x51 线性DP

    AcWing271. 杨老师的照相排列 思路 这是一个计数的题目,如果乱考虑,肯定会毫无头绪,所以我们从1号到最后一个依次进行安排. 经过反复实验,发现两个规律 每一行的同学必须是从左向右依次连续放置 ...

  8. 算法竞赛进阶指南0x35高斯消元与线性空间

    高斯消元 目录 高斯消元 ACWing207. 球形空间产生器(点击访问) 求解思路 代码 ACWing208. 开关问题(点击访问) 思路 代码 总结 欣赏 线性空间 定义 ACWing209. 装 ...

  9. 算法竞赛进阶指南0x14 Hash

    组成部分: 哈希函数: 链表 AcWing137. 雪花雪花雪花 因为所需要数据量过于大,所以只能以O(n)的复杂度. 所以不可能在实现的过程中一一顺时针逆时针进行比较,所以采用一种合适的数据结构. ...

随机推荐

  1. Java SPI 和 API,傻傻分不清?

    最近新写了一个中间件「运行时动态日志等级开关」,其中使用Java SPI机制实现了自定义配置中心,保证良好的扩展性. 项目地址,走过路过可以点个star :)https://github.com/sa ...

  2. ts中 any、unknown、never 、void的区别

    any.unknown.never .void的区别 any 表示任意类型,设置为any相当于对该变量关闭了TS的类型检测.不建议使用 let a;(隐式any) //声明变量不赋值,就是any 等效 ...

  3. OpenStack平台调度策略优化

    OpenStack平台报错分析 在OpenStack平台经历大并发的时候,比如同一个平台,大量的用户同时创建云主机(单个用户创建大量云主机不会触发此种现象),会达到云平台的性能瓶颈,导致创建云主机报错 ...

  4. web框架的本质、MVC框架MTV框架的介绍

    1.web框架的本质 所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,基于请求做出响应,客户都先请求,服务端做出对应的响应,按照http协议的请求协议发送请 ...

  5. ThinkPHP V6.0.12在php8.1下验证码出现问题

    一.问题描述 1.项目需求要求使用PHP8.1.*版本 2.运行程序发现验证码不生效报错如下: 二.错误描述 1.报错信息得出:从浮点(数字)到整数的隐式转换将失去精度 三.解决流程 1.找到报错文件 ...

  6. Azure DevOps (十三) 通过Azure Devops部署一个Go的Web应用

    前几篇文章中,我们分别实现通过azure来部署.NET和Springboot的应用,今天我们来研究一下如何部署一套Go的Web应用上去. 文章配套视频专栏: https://space.bilibil ...

  7. 一探 Vue 数据响应式原理

    一探 Vue 数据响应式原理 本文写于 2020 年 8 月 5 日 相信在很多新人第一次使用 Vue 这种框架的时候,就会被其修改数据便自动更新视图的操作所震撼. Vue 的文档中也这么写道: Vu ...

  8. 【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示

    前言: Wpf开发过程中,最经常使用的功能之一,就是用户控件(UserControl)了.用户控件可以用于开发用户自己的控件进行使用,甚至可以用于打造一套属于自己的UI框架.依赖属性(Dependen ...

  9. Python <算法思想集结>之抽丝剥茧聊动态规划

    1. 概述 动态规划算法应用非常之广泛. 对于算法学习者而言,不跨过动态规划这道门,不算真正了解算法. 初接触动态规划者,理解其思想精髓会存在一定的难度,本文将通过一个案例,抽丝剥茧般和大家聊聊动态规 ...

  10. 定制.NET 6.0的依赖注入

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 在本章中,我们将学习ASP.NET Core的依赖项注入(DI)以及如何自定义它. ...