51nod 3180 矩阵连乘
感觉区间 dp 还是要感性理解,但好像区间有套路的,这和石子合并很像,就根据题意模拟。
这个写法的区间比较巧妙,左右同时增加,相当于滑动窗口,因为一开始花费一个是0,所以注意dp的初始化。
#include<bits/stdc++.h> using namespace std; int n; // 矩阵的个数 long long dp[1005][1005]; // 动态规划表,dp[i][j]表示从矩阵i到矩阵j的最小乘法次数 long long a[1005]; // 存储矩阵的维度,a[i]表示第i个矩阵的行数,a[i+1]表示它的列数 int main(){ ios::sync_with_stdio(false); cin >> n; // 输入矩阵的个数(注意:实际输入的a数组长度是n+1,因为矩阵个数n需要n+1个维度来描述) memset(dp, 0, sizeof dp); // 初始化动态规划表,初始时所有乘法次数都为0 // 读取n+1个值,用于表示n个矩阵的维度 for(int i = 0; i <= n; i++){ cin >> a[i]; // 输入矩阵的维度信息 } // 动态规划部分,计算最小乘法次数 for(int len = 2; len <= n; len++){ // len是当前处理的矩阵子链长度,从2个矩阵开始 int r = len; // 初始化右端点 for(int j = 1; r <= n; j++, r++){ // j是左端点,r是右端点,遍历所有可能的子链区间[j, r] long long mi = 1e18; // 初始化mi为一个非常大的数,相当于无穷大 for(int k = j; k < r; k++){ // 枚举分割点k,将矩阵链[j, r]分成[j, k]和[k+1, r]两部分 // 计算分割成两部分的代价,再加上这两部分相乘的代价 mi = min(mi, dp[j][k] + dp[k+1][r] + a[j-1] * a[k] * a[r]); } dp[j][r] = mi; // 保存子链[j, r]的最小乘法次数 } } cout << dp[1][n]; // 输出从矩阵1到矩阵n的最小乘法次数 return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」