矩阵
描述#
\(N(2 \le N \le 100)\) 个矩阵相乘,求进行乘法的最少次数。
我们认为两个矩阵\(A(m \times n) \times B(n \times p)\) 的乘法次数为 \(m \times n \times p\) 次。
格式#
输入格式#
第一行是整数 \(N\)。
接下来 \(N\) 行是对每个矩阵的描述,一行两个整数 \(a,b~(1 \le a,b \le 50)\),\(a\) 表示行,\(b\) 表示列。
输入确保能够相乘。
输出格式#
一行输出最少乘法次数。
样例#
样例输入#
3
50 10
10 20
20 5
样例输出#
3500
题解#
这题思路说实话不是特别好找,主要就是要认识到矩阵之间不同的相乘顺序会导致最终乘法次数的不同。
\(f[i][j]\) 表示表示从第 \(i\) 个矩阵乘到第 \(j\) 个矩阵的最小乘法次数,即第 \(i, i+1, i+2, \dots \ , j-1, j\) 个矩阵相乘的最小乘法次数。
那么在我们该考虑怎样进行松弛,也就是该怎么列出状态转移方程。
这就是这题的精髓了:区间DP。用类似于 \(RMQ\) 算法中 \(st\) 算法和 \(Floyd\) 算法的思想,枚举一个断点 \(k\),那么我们可以得到状态转移方程为:
\[f[i][j] = \min (f[i][j],~f[i][k]+f[k+1][j] + (a[i] \times b[k] \times b[j]))
\]
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 110
using namespace std;
int n, f[N][N];
// f[i][j]表示从第i个矩阵乘到第j个矩阵的最小乘法次数
struct Matrix
{
int x, y;
}mtx[N];
int main()
{
memset(f, 0x3f, sizeof(f));
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d%d", &mtx[i].x, &mtx[i].y);
f[i][i] = 0;
}
for(int i = n; i; i--)
{
for(int j = 1; j <= n; j++)
for(int k = i; k < j; k++)
f[i][j] = min(f[i][j], f[i][k] + f[k+1][j] + mtx[i].x*mtx[k].y*mtx[j].y);
}
printf("%d", f[1][n]);
return 0;
}
作者:chy12321
出处:https://www.cnblogs.com/chy12321/p/14844910.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现