【矩阵快速幂】封装类及测试用例及样例

作者推荐

视频算法专题

通俗的说,就是矩阵的乘方。

封装类

核心代码

class CMat
{
public:// 矩阵乘法static vector<vector<long long>> multiply(const vector<vector<long long>>& a, const vector<vector<long long>>& b) {const int r = a.size(), c = b.front().size(),iK = a.front().size();assert(iK == b.size());vector<vector<long long>> ret(r, vector<long long>(c));for (int i = 0; i < r; i++){for (int j = 0; j < c ; j++) {for (int k = 0; k < iK; k++){ret[i][j] = (ret[i][j] + a[i][k] * b[k][j] ) % s_llMod;}}}return ret;}// 矩阵快速幂static vector<vector<long long>> pow( const vector<vector<long long>>& a, vector<vector<long long>> b, long long n) {vector<vector<long long>> res = a;for (; n; n /= 2) {if (n % 2) {res = multiply(res, b);}b = multiply(b, b);}return res;}static vector<vector<long long>> TotalRow(const vector<vector<long long>>& a){vector<vector<long long>> b(a.front().size(), vector<long long>(1, 1));return multiply(a, b);}
protected:const static long long s_llMod = 1e9 + 7;
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{vector<vector<long long>> pre = { {1,2} };vector<vector<long long>> mat = { {2,3},{1,10} };{	auto res = CMat::pow(pre, mat, 0);Assert(pre, res);}{auto res = CMat::multiply(pre, mat);Assert(vector<vector<long long>>{ {4, 23}}, res);auto res2 = CMat::pow(pre, mat,1);Assert(res2, res);}{auto res = CMat::pow(pre, mat, 2);auto res1 = CMat::multiply(pre, mat);auto res2 = CMat::multiply(res1, mat);Assert(res2, res);Assert(vector<vector<long long>>{ {31, 242}}, res);};for (int i = 3; i < 100; i++){auto res = pre;for (int j = 0; j < i; j++){res = CMat::multiply(res, mat);}auto res2 = CMat::pow(pre, mat, i);Assert(res2, res);}}

具体例子

题目、分析和原理见:

【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II

原解法用二维表示状态,改成一维。 i是缺勤数量,j是连续迟到数,新的状态为:3*i+j
6种状态,故转移矩阵为6行6列,故结果矩阵为6列,6个数据1行就足够了。
令旧结果矩阵为mat1,转移矩阵为mat2,新矩阵为mat3,K mat1的列数,mat2的行数。则:
mat3[r][c] = Sum [ 0 , k ) i ^{i}_{[0,k)} [0,k)i(mat1[r][i]*mat2[i][c])

i在mat1中列号,在mat2中是行号。 也就是旧状态在第几列,mat2就在第几行。
新状态就是mat2的行号。

class Solution {
public:int checkRecord(int n) {vector<vector<long long>> pre(1, vector<long long>(6));//1行6列	pre[0][0] = 1;vector<vector<long long>> mat(6, vector<long long>(6));{	//之前的状态在pre是第几列,矩阵中就是第几行。新状态的列号就矩阵的列号//处理一次缺勤 ,缺勤两次排除for (int i = 0; i < 3; i++){mat[i][3]++;}//处理请假for (int i = 0; i < 2; i++){for (int j = 0; j < 2; j++){const int pre = 3 * i + j;mat[pre][pre + 1]++;}}//处理正常for (int i = 0; i < 2; i++){for (int j = 0; j < 3; j++){const int pre = 3 * i + j;const int cur = 3 * i;mat[pre][cur]++;}}}auto res = CMat::pow(pre, mat, n);res = CMat::TotalRow(res);return res[0][0];}
};

测试用例

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
Assert(v1[i], v2[i]);
}
}

int main()
{
int n;
{
Solution sln;
n = 0;
auto res = sln.checkRecord(n);
Assert(1, res);
}
{
Solution sln;
n = 1;
auto res = sln.checkRecord(n);
Assert(3, res);
}
{
Solution sln;
n = 2;
auto res = sln.checkRecord(n);
Assert(8, res);
}
{
Solution sln;
n = 3;
auto res = sln.checkRecord(n);
Assert(19, res);
}
{
Solution sln;
n = 4;
auto res = sln.checkRecord(n);
Assert(43, res);
}
{
Solution sln;
n = 5;
auto res = sln.checkRecord(n);
Assert(94, res);
}
{
Solution sln;
n = 6;
auto res = sln.checkRecord(n);
Assert(200, res);
}
{
Solution sln;
n = 7;
auto res = sln.checkRecord(n);
Assert(418, res);
}
{
Solution sln;
n = 10101;
auto res = sln.checkRecord(n);
Assert(183236316, res);
}
}

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 **C+

+17**
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/623215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Python管理MySQL数据库,有录播直播私教课视频教程

查看所有数据库 from mysql.db_object import Databasedb Database(host"localhost",port3306,database"",username"root",password"zhangdapeng520" ) print(db.get_all_database())删除数据库 from mysql.db_object import Datab…

Python 面向对象之元类

Python 面向对象之元类 【一】一切皆对象 【1】元类 元类&#xff08;metaclass&#xff09;是Python中用于创建类的类。在Python中&#xff0c;类是对象&#xff0c;而元类就是类的类它们控制类的创建过程&#xff0c;允许你定制类的行为Python中内置的默认元类是type我们用…

Android JNI与Java类的转换调用

1. 前言 一般在Android中&#xff0c;对于JNI的调用&#xff0c;基本的数据类型就能满足要求了&#xff0c;具体可以看我的这一篇文章 : Android JNI/NDK 入门从一到二&#xff0c;但是最近在项目中遇到了基本类型满足不了需要的情况&#xff0c;需要在JNI中创建并操作Java类&…

Rust-语句和表达式

if-else Rust中if-else表达式的作用是实现条件分支。if-else表达式的构成方式为&#xff1a;以if关键字开头&#xff0c;后面跟上条件表达式&#xff0c;后续是结果语句块&#xff0c;最后是可选的else块。条件表达式的类型必须是bool。 if-else结构还可以当表达式使用 loop …

如何用LLM和自有知识库搭建智能agent?

用LangChain建立知识库&#xff0c;文末中也推荐其他方案。 项目源码&#xff1a;ChatPDF实现 LangChain Indexes使用 对加载的内容进行索引&#xff0c;在indexes中提供了一些功能&#xff1a; Document Loaders&#xff0c;加载文档Text Splitters&#xff0c;文档切分V…

nautilus`文件管理器打开文件管理器

使用nautilus文件管理器打开文件管理器&#xff0c;并使用管理员权限。以下是使用命令行的步骤&#xff1a; 打开终端&#xff08;命令行界面&#xff09;&#xff0c;你可以通过按下Ctrl Alt T组合键来打开终端。 在终端中&#xff0c;使用以下命令以管理员权限打开文件管理…

开发实践5_后台管理^/ 分_页器

以下学习 朔宁夫 开发课 。&#xff08;Python&#xff09; 一 基本使用 创建超级用户 terminal // python manage.py createsuperuser 访问地址 //Log in | Django site adminhttp://127.0.0.1:8000/admin/login/?next/admin/ superuserr login django自带admin功能。其…

一文读懂「Prompt Engineering」提示词工程

在了解提示过程之前&#xff0c;先了解一下什么是提示prompt&#xff0c;见最后附录部分 一、什么是Prompt Engingering&#xff1f; 提示工程&#xff08;Prompt Engingering&#xff09;&#xff0c;也被称为上下文提示&#xff08;In-Context Prompting&#xff09;&#x…

Django项目中的默认文件都有什么用

manager.py&#xff1a; 是django用于管理本项目的命令行工具&#xff0c;之后进行站点运行&#xff0c;数据库自动生成等都是通过本文件完成。 djangoStudy/__init__.py&#xff1a; 告诉python该目录是一个python包&#xff0c;暂无内容&#xff0c;后期一些工具的初始化可…

【数据库】间隙锁Gap Lock

什么是间隙锁 间隙锁&#xff08;Gap Lock&#xff09;&#xff1a;间隙锁是&#xff08;RR级别下&#xff09;一个在索引记录之间的间隙上的锁&#xff0c;可以是两个索引记录之间&#xff0c;也可能是第一个索引记录之前或最后一个索引之后的空间。间隙锁&#xff08;Gap Lo…

Github登录时,要二次验证.Github 2FA登录问题

2023下半年, Github登录时,要二次验证. 点击“Enable 2FA now”跳到2FA验证界面。 点setup key是到secret串。 这里有一个可以不用app的验证方法。填入secret串,运行后,会得到验证码. https://blog.csdn.net/dejavu_980323/article/details/132318107 按照这个文章,得到验证…

记csv、parquet数据预览一个bug的解决

文章目录 一、概述二、实现过程1. 业务流程2. 业务逻辑3. 运行结果 三、bug现象1. 单元测试2.运行结果 三、解决思路1. 思路一2. 思路二 一、概述 工作中遇到通过sparksession解析csv、parquet文件并预览top100的需求。 二、实现过程 1. 业务流程 #mermaid-svg-Tzp1pJTvJunU…

227. Basic Calculator II

227. Basic Calculator II class Solution:def calculate(self, s: str) -> int:ititer(re.split(r([\\-\*\/]),s))lastansint(next(it))for op in it:nint(next(it))if op in -:if op-:n-nansnelse:if op*:nlast*nelse:nint(last/n)ansans-lastnlastnreturn ans 注意这个…

分布式任务调度平台XXL-JOB使用(二)

说明&#xff1a;之前总结过在CentOS系统里使用XXL-JOB。但在代码开发阶段&#xff0c;我们有时需要在本地环境测试定时任务代码&#xff0c;本文介绍如何在Windows系统使用XXL-JOB。 下载 &#xff08;1&#xff09;下载代码&#xff0c;解压打开 首先&#xff0c;去Github…

多线程实现方式二

这里写目录标题 RunnableRunable接口实现多线程使用Runnable接口实现多线程的好处线程同步 - 三个窗口买票lock实现同步锁 Runnable Runable接口实现多线程 实现 Runnable 接口 定义一个类 MyRunnable 实现 Runnable 接口 在 MyRunnable 类中重写 run() 方法 创建 Thread 类…

Python系列(3)—— 变量

变量 一、变量命名规范二、变量赋值三、变量的数据类型四、变量的作用域五、变量类型转换 Python编程中&#xff0c;变量是存储数据的容器。它们用于存储各种数据类型&#xff0c;如整数、浮点数、字符串、列表、字典等。理解变量及其工作原理是Python编程的基础。 一、变量命…

在Android原生项目中 创建 Flutter模块

前言 应用场景&#xff1a;在已有的Android原生项目中&#xff0c;引入Flutter模块&#xff0c;摸索了两天&#xff0c;终于给整出来了&#xff1b; 如果是新项目&#xff0c;最好直接创建Flutter项目&#xff0c;然后在Fluter的 android / ios目录中&#xff0c;写原生代码&…

深思熟虑可能性模型介绍与使用

深思熟虑可能性模型介绍与使用 如何联系我 作者&#xff1a;鲁伟林 邮箱&#xff1a;thinking_fioa163.com或vlinyes163.com 版权声明&#xff1a;文章和记录为个人所有&#xff0c;如果转载或个人学习&#xff0c;需注明出处&#xff0c;不得用于商业盈利行为。 背景 20…

力扣27-移除元素

移除元素 题目链接 解题思路 ans为左指针 循环遍历为右指针 右指针开始遍历整个列表&#xff0c;如果指针所指的元素与val值不等&#xff0c;那么这个元素不能被删除&#xff0c;将其放入到左指针索引处。 因为return的是列表的长度&#xff0c;ans恰好也是删除完元素后列表的…

[牛客周赛复盘] 牛客周赛 Round 28 20240114

[牛客周赛复盘] 牛客周赛 Round 28 20240114 总结A\B1. 题目描述2. 思路分析3. 代码实现 小红的炸砖块1. 题目描述2. 思路分析3. 代码实现 小红统计区间&#xff08;easy&#xff09;1. 题目描述2. 思路分析3. 代码实现 小红的好数组1. 题目描述2. 思路分析3. 代码实现 小红统…