矩阵连乘 /// 区间DP oj1900
Posted _Jessie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵连乘 /// 区间DP oj1900相关的知识,希望对你有一定的参考价值。
题目大意:
输入t ;t为测试用例个数
接下来t个测试 每个测试用例
第一行输入n; n为矩阵个数 保证n个矩阵依序是可乘的
接下来n行 每行输入p,q;p为长度q为宽度
对给定的n个矩阵确定一个计算次序使得总的乘法次数最少
并输出该最优值
Sample Input
1
4
50 10
10 40
40 30
30 5
Sample Output
10500
理论讲解
https://www.cnblogs.com/Jason-Damon/p/3231547.html
https://blog.csdn.net/wangmengmeng99/article/details/50134673
#include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int a[55],dp[55][55]; //int pre[55][55]; // /* pre[i][j]=k 即 i到j之间由k断开 // 借此输出最小乘数的表达式 */ //void print_chain(int i, int j) //{ // 递归输出最小连乘的表达式 // if (i==j) printf("矩阵%d",i); // else // { // printf("("); // print_chain(i,pre[i][j]); // printf("*"); // print_chain(pre[i][j]+1,j); // printf(")"); // } //} int main() { int t; while(~scanf("%d",&t)) { while(t--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int p,q; scanf("%d%d",&p,&q); if(i==1) a[0]=p; a[i]=q; } // 第一个存行和列 之后的只存列 //memset(pre,0,sizeof(pre)); memset(dp,INF,sizeof(dp)); // 初始化无穷大 for(int i=1;i<=n;i++) dp[i][i]=0; /// 只有本身一个矩阵时 矩阵乘积为0 for(int i=2;i<=n;i++) /// 枚举矩阵个数 由从小推大 for(int l=1;l<=n-i+1;l++) /// 枚举左端下标 { int r=l+i-1; // 根据个数 得到右端下标 dp[l][r]=dp[l+1][r]+a[l-1]*a[l]*a[r]; /// dp[l][r]视为 l矩阵*(dp[l+1][r])矩阵 //pre[l][r]=l; for(int k=l+1;k<r;k++) dp[l][r]=min(dp[l][r], dp[l][k]+dp[k+1][r]+a[l-1]*a[k]*a[r]); /// dp[l][r]视为 (dp[l][k])矩阵*(dp[k+1][r])矩阵 // 当需要记录 pre[][] 时 // { // int tmp=dp[l][k]+dp[k+1][r]+a[l-1]*a[k]*a[r]; // if(tmp<dp[l][r]) dp[l][r]=tmp, pre[l][r]=k; // } } // for(int i=1;i<=n;i++) // { // for(int j=1;j<=n;j++) // printf("%d ",pre[i][j]); // // printf("%d ",dp[i][j]); // printf("\\n"); // } // print_chain(1,n); // 最小连乘表达式 // printf("\\n"); printf("%d\\n",dp[1][n]); // 最小连乘次数 } } return 0; }
以上是关于矩阵连乘 /// 区间DP oj1900的主要内容,如果未能解决你的问题,请参考以下文章