首页 > 编程语言 >矩阵连乘(动态规划)(C/C++)最详尽代码注释

矩阵连乘(动态规划)(C/C++)最详尽代码注释

时间:2024-09-15 18:21:49浏览次数:9  
标签:连乘 分隔 int 矩阵 C++ 最优 乘法

写在所有的前面:

本文采用C/C++实现代码

目录

题目说明

题目

题目出处

广西大学oj
22级《算法设计与分析》第二次作业
链接:https://oj.gxu.edu.cn/contest/625/problem/0001

题目描述Description

在这里插入图片描述

输入Input

这里是引用

输出Output

这里是引用

样例Sample

输入:

3
10 100 5 50

输出:

7500

限制Hint

n ≤ 100

解答说明

方案1:最优分隔点法(动态规划)

解题思路

薛猫颚的腚《动态规划之矩阵连乘问题详细解读(思路解读+填表+代码)》
这位大佬的讲解超详尽了直接转链节!!!
https://blog.csdn.net/weixin_44952817/article/details/110124596
我对代码部分的注释做了一些优化(挑战本题最详尽代码注释)

代码实现

想用哪个语言就用对应的头文件

c语言头文件:
#include<stdio.h>
c++头文件
#include<iostream>
using namespace std;
主代码部分:(详尽版本1)
const int N = 110;//常量
int A[N];//矩阵规模
int m[N][N];//最优解需要做的乘法次数
int s[N][N];//最优解所经历的“分隔点k”

void MatrixChain(int n)
{
	int r, i, j, k;//连乘矩阵个数r,连乘开始点i,连乘结束点j,分隔点k
	for (i = 0; i <= n; i++)//初始化对角线
	{
		m[i][i] = 0;//单个矩阵乘法次数为 0
	}
	for (r = 2; r <= n; r++)//r个矩阵连乘
	{
		//r个矩阵的r-1个空隙中依次测试最优点
		for (i = 1; i <= n - r + 1; i++)//测试区间连乘从i开始
		{
			j = i + r - 1;//到j结束,共r个
			m[i][j] = m[i][i] + m[i + 1][j] + A[i - 1] * A[i] * A[j];//记录第一个分隔点对应乘法次数
			s[i][j] = i;//记录第一个分隔点
			for (k = i + 1; k < j; k++)//变换分隔位置,逐一测试
			{
				int t = m[i][k] + m[k + 1][j] + A[i - 1] * A[k] * A[j];//临时记录当前分隔点对应乘法次数
				if (t < m[i][j])//更新最优分隔点
				{
					m[i][j] = t;//从i到j的最优乘法次数
					s[i][j] = k;//分隔点
				}
			}
		}
	}
}

void print(int i, int j)//打印当前连乘矩阵
{
	if (i == j)//分隔到单个矩阵
	{
		printf("A[%d]", i);//输出该矩阵
		return;//返回上一级
	}
	printf("(");//分隔前左括号
	print(i, s[i][j]);//当前左端,到最优分隔点
	print(s[i][j] + 1, j);//最优分隔点,到当前右端
	printf(")");//分隔前右括号
}

int main()
{
	int n;//n个矩阵
	scanf("%d", &n);//输入
	for (int i = 0; i <= n; i++)
	{
		scanf("%d", &A[i]);//输入n个矩阵的n+1个数据
	}
	MatrixChain(n);//动态规划遍历记录最优分隔点及其对应乘法次数,n为测试矩阵个数
	printf("最佳添加括号的方式为:");
	print(1, n);//打印所有矩阵的连乘方法(括号分隔表示)
	printf("\n最小计算量的值为:%d\n", m[1][n]);//所有矩阵连乘的最优乘法次数
	return 0;
}
主代码部分(题目对应版本)

只打印乘法次数

const int N = 110;//常量
int A[N];//矩阵规模
int m[N][N];//最优解需要做的乘法次数
int s[N][N];//最优解所经历的“分隔点k”

void MatrixChain(int n)
{
	int r, i, j, k;//连乘矩阵个数r,连乘开始点i,连乘结束点j,分隔点k
	for (i = 0; i <= n; i++)//初始化对角线
	{
		m[i][i] = 0;//单个矩阵乘法次数为 0
	}
	for (r = 2; r <= n; r++)//r个矩阵连乘
	{
		//r个矩阵的r-1个空隙中依次测试最优点
		for (i = 1; i <= n - r + 1; i++)//测试区间连乘从i开始
		{
			j = i + r - 1;//到j结束,共r个
			m[i][j] = m[i][i] + m[i + 1][j] + A[i - 1] * A[i] * A[j];//记录第一个分隔点对应乘法次数
			s[i][j] = i;//记录第一个分隔点
			for (k = i + 1; k < j; k++)//变换分隔位置,逐一测试
			{
				int t = m[i][k] + m[k + 1][j] + A[i - 1] * A[k] * A[j];//临时记录当前分隔点对应乘法次数
				if (t < m[i][j])//更新最优分隔点
				{
					m[i][j] = t;//从i到j的最优乘法次数
					s[i][j] = k;//分隔点
				}
			}
		}
	}
}

int main()
{
	int n;//n个矩阵
	scanf("%d", &n);//输入
	for (int i = 0; i <= n; i++)
	{
		scanf("%d", &A[i]);//输入n个矩阵的n+1个数据
	}
	MatrixChain(n);//动态规划遍历记录最优分隔点及其对应乘法次数,n为测试矩阵个数
	printf("%d\n", m[1][n]);//所有矩阵连乘的最优乘法次数
	return 0;
}

其他解释

大佬写的已经非常好了,这里仅做了一些输入输出代码上的修改(将头文件换掉可以跑c语言),和代码注释的详尽化,浅浅投一下稿啦

标签:连乘,分隔,int,矩阵,C++,最优,乘法
From: https://blog.csdn.net/just_do_it_sq/article/details/142218288

相关文章

  • C++链接的那些事
    接上文OK!Rightnow!  Let's go!今天我们来谈谈链接,什么是链接,C++链接实际上做什么的?链接是一个过程,当我们从源C++文件转到实际的可执行文件(二进制文件)。第一阶段是编译源文件,一旦我们把文件编译好,就需要通过一个叫做链接的过程,现在链接的主要工作是找到每个符号和......
  • C++编译 链接 执行那些事
    OK!Rightnow!  Let's go!如何从源文件开始,实际的文本文档到可执行的二进制代码,写C++程序的基本流程。实际是你有一些C++的源文件,然后将这些源文件给到编译器,编译器将其转成二进制的东西,二进制的东西可能是某种库,或者是可执行的程序。在#符号之后的都是预处理语句......
  • 「数组」堆排序 / 大根堆优化(C++)
    目录概述核心概念:堆堆结构数组存堆思路算法过程up()down()Code优化方案大根堆优化Code(pro)复杂度总结概述在「数组」快速排序/随机值优化|小区间插入优化(C++)中,我们介绍了三种基本排序中的冒泡排序与分治思想结合的算法:快速排序。本文我们来讲第二种基本排......
  • 详解c++多态---上
    virtual关键字1.可以修饰原函数,为了完成虚函数的重写,满足多态的条件之一。classPerson{public:virtualvoidBuyTicket(){cout<<"买票-全价"<<endl;}};classStudent:publicPerson{public:virtualvoidBuyTicket(){cout<<"买票-半价"<<......
  • c++走出迷宫改良版2
    本文对上期做了删改话不多说上代码:注彩色输出部分代码出自博主夜若渊#include<bits/stdc++.h>#include<windows.h>#include<stdlib.h>#include<cstdio>#include<iostream>#include<string>#include<stdio.h>#include<ctime>#include<conio.h&g......
  • 深入解析C++函数指针:掌握游戏开发中的关键技术
    深入解析C++函数指针:掌握游戏开发中的关键技术C++作为一门经典的编程语言,因其强大的性能和灵活性,被广泛应用于游戏开发。而函数指针作为C++中的一个重要概念,在游戏开发中更是扮演着不可或缺的角色。对于想要深入掌握C++并在游戏开发领域站稳脚跟的开发者来说,理解并灵活运用函数指......
  • C++入门补充语法
    1、C和C++的区别                首先C++是包含C语言的,C语言中的所有语法在C++中都可以应用,因为C语言语法限制过多导致许多东西实现起来不方便,所以C++又制订了一系列的语法来补充C语言的不足。2、命名空间2.1命名空间为什么要使用命名空间,下面我们使用一段......
  • C++资源管理浅谈
    引言:            在计算机编程语言的学习与实践中,自然避免不了与计算机的资源管理打交道。所谓的资源就是,一旦用了它,将来就必须还给系统,如果用户不这么做,那糟糕的事情便会发生。在开始谈及C++的资源管理之前,先来聊聊何为计算机的资源,以及为何要管理计算机的资......
  • 力扣最热一百题——螺旋矩阵
    目录题目链接:54.螺旋矩阵-力扣(LeetCode)题目描述示例提示:解法一:模拟1.边界初始化2.循环遍历矩阵3.从左到右遍历上边界4.从上到下遍历右边界5.从右到左遍历下边界6.从下到上遍历左边界7.结束条件代码执行流程总结Java写法:运行时间以及内存消耗C++写法......
  • 【C++】string类中常用函数的模拟实现
    【C++】string类中常用函数的模拟实现1.string.h2.Text.cpp1.string.h#include<assert.h>namespacewch{ classstring { public: typedefchar*iterator; typedefconstchar*const_iterator; iteratorbegin() { return_str; } itera......