矩阵链相乘的乘法次数(动态规划)

news2024/10/5 23:26:13
Description
设 A1, A2, …, An 为矩阵序列,Ai 是阶为 Pi − 1 * Pi 的矩阵 i = 1, 2, …, n.

试确定矩阵的乘法顺序,使得计算 A1A2…An 过程中元素相乘的总次数最少.

Input
多组数据

第一行一个整数 n(1≤n≤300) ,表示一共有 n 个矩阵.

第二行 n + 1 个整数 P0, P1, …, Pn(1≤Pi≤100) ,第i个矩阵的行数为Pi − 1,列数为Pi.

Output
对于每组数据输出最少的元素乘法次数.

Sample Input
5
74 16 58 58 88 80 
5 
10 1 50 50 20 5 
Sample Output
342848
3650

该题是算法动态规划练习题

该题首先要清楚地认识和理解题意

首先,理解一次矩阵乘法会产生多少次乘法运算

例如给定两个矩阵(10 * 5)与(5 * 20)

会产生的乘法次数为 10*5*20=1000次

然后我们要理解当存在多个矩阵相乘时,乘的顺序不同,最终乘法运算的总次数也是不同的!

 

到这里,我们按照动态规划的思想开始解答

我们先定义一个数组来存储子问题,这里dp[i][j]定义为矩阵[i,j]相乘的最小总次数(其中1<=i<=j<=n,n为矩阵个数)

然后就是找到子问题和子问题之间的关系(求递推方程)

很明显的是当i==j时,此时只有一个矩阵,因此乘法运算次数肯定为0

而j==i+1时,此时只有两个矩阵,因此乘法运算次数肯定为这两个矩阵的相乘乘法次数  

再往上推,当有三个矩阵时,我们需要进行划分了,即划分为左边两个矩阵先乘还是右边两个矩阵先乘

因此这里我们定义一个划分变量k,定义i<=k<j,这样定义是为了方便后续计算

例如只有两个矩阵的时候,我们计算乘法次数公式就可以定义为p[i-1]*p[k]*p[j],

 然后对每一次划分的结果都进行计算乘法次数,同时取最小值不断更新我们的dp数组即可

下面给出两个版本

#include<cstdio>

using namespace std;

int MAX=310,inf=0x3f3f3f3f;
int n;
int p[310];
int dp[310][310];//dp[i][j]定义为矩阵[i,j]相乘的最小总次数 

int fun(int i,int j){//计算矩阵[i,j]相乘的最小总次数 (左闭右闭)
	for(int k=i;k<j;k++){//枚举划分的位置 
		int temp=fun(i,k)+fun(k+1,j)+p[i-1]*p[k]*p[j];
		if(temp<dp[i][j]){
			dp[i][j]=temp;
		}
	}
	return dp[i][j];
}

int main(){
	while(scanf("%d",&n)!=EOF){
		for(int i=0;i<=n;i++){
			scanf("%d",&p[i]);
		}
		for(int i=0;i<MAX;i++){
			for(int j=0;j<MAX;j++){
				if(i==j){
					dp[i][j]=0;
				}else{
					dp[i][j]=inf;//初始化 
				}
			}
		}
		int res=fun(1,n);
		printf("%d\n",res);
	}
	
	return 0;
} 
#include<cstdio>

using namespace std;

int MAX=310,inf=0x3f3f3f3f;
int n;
int p[310];
int dp[310][310];//dp[i][j]定义为矩阵[i,j]相乘的最小总次数 

void fun(int beg,int endd){//计算矩阵[i,j]相乘的最小总次数 (左闭右闭)
	for(int r=2;r<=n;r++){//子问题的大小 
		for(int i=1;i<=n-r+1;i++){//左边界 
			int j=i+r-1;//右边界 
			for(int k=i;k<j;k++){//枚举划分 
				int temp=dp[i][k]+dp[k+1][j]+p[i-1]*p[k]*p[j];
				if(temp<dp[i][j]){
					dp[i][j]=temp;
				}
			}
		}
	}
}

int main(){
	while(scanf("%d",&n)!=EOF){
		for(int i=0;i<=n;i++){
			scanf("%d",&p[i]);
		}
		for(int i=0;i<MAX;i++){
			for(int j=0;j<MAX;j++){
				if(i==j){
					dp[i][j]=0;
				}else{
					dp[i][j]=inf;//初始化 
				}
			}
		}
		fun(1,n);
		int res=dp[1][n];
		printf("%d\n",res);
	}
	
	return 0;
} 

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

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

相关文章

真题详解(计算机知识)-软件设计(五十四)

真题详解&#xff08;归并&#xff09;-软件设计&#xff08;五十三)https://blog.csdn.net/ke1ying/article/details/130254861 若无条件转移汇编指令采用直接寻址&#xff0c;则该指令功能是将指令中的地址码送入_____? PC&#xff08;程序计数器&#xff09; 程序计数器&…

10种黑客类型,你知道几种?

黑客一般有 10 种类型 1、白帽黑客 白帽黑客是指通过实施渗透测试&#xff0c;识别网络安全漏洞&#xff0c;为政府及组织工作并获得授权或认证的黑客。他们也确保保护免受恶意网络犯罪。他们在政府提供的规章制度下工作&#xff0c;这就是为什么他们被称为道德黑客或网络安全…

Kyligence Zen 产品体验 --- 初识庐山真面目

简介 Kyligence Zen 是一款数据分析工具&#xff0c;其市场定位是一站式云端指标平台。它基于 Kyligence 核心 OLAP&#xff08;On-Line Analytical Processing&#xff09; 能力打造&#xff0c;提供集业务模型、指标管理、指标加工、数据服务于一体的一站式服务。 其基本的…

Linux: SPI 驱动

文章目录 1. 前言2. SPI 总线驱动2.1 SPI 总线拓扑2.2 SPI 总线工作模式2.3 SPI 总线驱动编写 3. SPI 从设驱动4. SPI 用户空间接口4.1 创建 SPI 总线用户空间字符设备节点4.2 操作 SPI 总线用户字符设备节点 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0…

百趣代谢组学分享,三阴性乳腺癌铁死亡异质性的揭示

百趣代谢组学分享文章标题&#xff1a;Ferroptosis heterogeneity in triple-negative breast cancer reveals an innovative immunotherapy combination strategy 发表期刊&#xff1a;Cell Metabolism 影响因子&#xff1a;31.373 作者单位&#xff1a;复旦大学附属肿瘤医…

DFS与BFS|树与图的遍历:拓扑排序

深度优先搜索DFS DFS每次往最深处搜&#xff0c;搜到叶子节点就返回&#xff0c;然后继续搜&#xff0c;特点&#xff1a;走到头才返回&#xff0c;返回并不是返回最开始&#xff0c;而是每次返回上一层之后&#xff0c;再看这一层能不能往下搜 DFS有回溯和剪枝。返回上一层的过…

维基百科收录企业或品牌词条的规则解析

作为一家知名企业&#xff0c;开展国外市场营销的前提需要做好海外网络口碑营销&#xff0c;解决品牌信任的问题。小马识途营销顾问近来接到很多关于维基百科的咨询&#xff0c;其实做海外营销的企业倒是很有营销意识&#xff0c;主动寻求创建维基百科的很多&#xff0c;但并不…

138. 复制带随机指针的链表

给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。新节点的 n…

ASEMI代理ADCMP600BKSZ-REEL7原装ADI车规级ADCMP600BKSZ-REEL7

编辑&#xff1a;ll ASEMI代理ADCMP600BKSZ-REEL7原装ADI车规级ADCMP600BKSZ-REEL7 型号&#xff1a;ADCMP600BKSZ-REEL7 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;SC-70-5 批号&#xff1a;2023 引脚数量&#xff1a;5 工作温度&#xff1a;-40C~125C 安装类型&am…

【从零开始学Skynet】实战篇《球球大作战》(四):分布式登录系统

处理玩家的登录&#xff0c;是服务端框架的主要功能之一。分布式系统涉及多个服务&#xff0c;让它们相互配合不产生冲突是一大难点。 1、登录流程 分布式服务端的登录功能要处理好如下两个问题&#xff1a; 问题一&#xff1a;完成角色对象的构建和销毁。如下图所示&#xf…

虹科Panorama SCADA平台连接OPC UA服务器操作详解

一、前言 虹科Panorama SCADA平台支持丰富的通信传输协议&#xff0c;其中包括OPC UA/DA、SNMP、Modbus、BACnet、IEC 61850、MQTT等多种常用的协议类型。OPC UA 采用简单的客户端/服务器的机制进行通信&#xff0c;服务器可在网络中提供大量信息&#xff0c;如有关 CPU、OPC …

pyecharts从入门到精通-地图专题Map-带时间轴与网格的复杂绘图

文章目录 参考安装与查看pyecharts地图实现-Geo导入依赖生成数据集生成2013-2018年的各个省份GDP数据生成2013-2018年的时间列表生成2013-2018年的总GDP设置visulmap的最大最小值范围 生成2013年的网格组合图提取2013年的数据测试绘制map地图绘制折线图line绘制折线图bar绘制折…

图片加水印的简单方法

图片加水印的简单方法~许多小伙伴都习惯在需要对外发布的图片上添加水印&#xff0c;添加水印后就不必担心图片被盗用或被用于其它不良目的&#xff0c;给我们造成不好的影响。然而&#xff0c;许多用户不知道如何为图片添加水印&#xff0c;也不知道应该选择哪种软件来进行操作…

C/C++|物联网开发入门+项目实战|空间读写|非字符空间|返回值内部实现|嵌入式C语言高级|C语言函数的使用(2)-学习笔记(12)

文章目录 空间的读写作用实现strlen实现strcpy 非字符空间void* 返回值返回连续空间类型示例&#xff1a; 函数内部实现示例&#xff1a; 参考&#xff1a; 麦子学院-嵌入式C语言高级-C语言函数的使用 空间的读写 void fun(char *p); const char *p 只读空间&#xff0c;只为…

多功能PDF工具合集:PDF Squeezer - PDF Toolbox Mac

PDF Squeezer - PDF Toolbox Mac是多功能PDF工具合集。专为操作 PDF 文件而设计&#xff0c;包含几乎所有你能想象到的操作&#xff0c;例如&#xff1a;压缩、合并、拆分、提取、插入、提取图像、转换图像、提取文本、排序、加密等。如果你正在为操作PDF文件发愁&#xff0c;快…

关于yolov8的一些理解

文章目录 1.前言2.创新点及工作3. 网络结构3.1 BackBone3.1.1 C2F3.1.2 结构微调3.1.2 SPPF 3.2 Neck3.3 Head 4.正样本匹配策略4.1 静态分配策略&动态分配策略4.2 TaskAlignedAssigner 5.损失函数5.1 概述5.2 Distribution Focal Loss 6.总结 1.前言 YOLOv8 是 ultralyti…

在Eclipse中安装配置JDK11

下载安装包 从请官方下载&#xff0c;地址为&#xff1a;https://www.oracle.com/java/technologies/javase-jdk11-downloads.html&#xff0c;选择相应的版本下载即可。注意&#xff0c;现在需要注册才能下载。 ** ** 安装JDK11 使用下载的安装包进行安装&#xff0c;双击可…

Hyperledger Fabric 2.x 环境搭建

一、说明 区块链网络的核心是分布式账本&#xff0c;在这个账本中记录了网络中发生的所有交易信息。 Hyperledger Fabric 是一个是开源的&#xff0c;企业级的&#xff0c;带权限的分布式账本解决方案的平台。Hyperledger Fabric 由模块化架构支撑&#xff0c;并具备极佳的保…

拉格朗日粒子扩散模式FLEXPART

为了高效、精准地治理区域大气污染&#xff0c;需要弄清污染物的来源。拉格朗日粒子扩散模式FLEXPART通过计算点、线、面或体积源释放的大量粒子的轨迹&#xff0c;来描述示踪物在大气中长距离、中尺度的传输、扩散、干湿沉降和辐射衰减等过程。该模式既可以通过时间的前向运算…

Pytorch基础 - 7. torch.transpose() 和 torch.permute()

目录 1. torch.transpose(dim0, dim1) 2. torch.permute(dims) 3. 在转置函数之后使用view() PyTorch中使用torch.transpose() 和 torch.permute()可对张量进行维度的转置&#xff0c;具体内容如下&#xff1a; 1. torch.transpose(dim0, dim1) 参数: 需要转置的两个维度…