题意:给你n个矩阵,让你连乘,怎么样处理先乘哪两个后乘哪两个 会导致计算次数最少,简单线性数学知识:矩阵乘法的 运算次数是跟乘的顺序有关的,并且输出来
这个数据输出是比较繁琐的,还好前面做过几道 都是类似于记录路径 并输出的,所以很熟练的用递归解决了
这是一道矩阵连乘问题,区间DP,典型的经典例子
有详细介绍的博客 :http://www.cnblogs.com/liushang0419/archive/2011/04/27/2030970.html
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> //#define ll long long #define ll __int64 #define eps 1e-7 #define inf 0xfffffff //const ll INF = 1ll<<61; using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int > P; //vector<pair<int,int> > ::iterator iter; // //map<ll,int >mp; //map<ll,int >::iterator p; //#define IN freopen("c:\\Users\\linzuojun\\desktop\\input.txt", "r", stdin) //#define OUT freopen("c:\\Users\\linzuojun\\desktop\\output.txt", "w", stdout) int dp[10 + 5][10 + 5]; int path[10 + 5][10 + 5]; typedef struct Node { int r,c; int id; }; Node node[1000 + 5]; void Printf(int x,int y) { if(x == y) { cout<<"A"<<x + 1; return; } cout<<"("; Printf(x,path[x][y]); cout<<" x "; Printf(path[x][y] + 1,y); cout<<")"; } void clear() { memset(dp,0,sizeof(dp)); memset(path,0,sizeof(path)); } int main() { int n; int Case = 0; while(cin>>n,n) { clear(); for(int i=0;i<n;i++) { cin>>node[i].r>>node[i].c; node[i].id = i; } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) if(i == j) dp[i][j] = 0; else dp[i][j] = inf; } for(int r=1;r<n;r++) { for(int i=0;i<n-r;i++) { int j = i + r; for(int k=i;k<j;k++) { if(dp[i][j] > dp[i][k] + dp[k + 1][j] + node[i].r * node[k + 1].r *node[j].c) { dp[i][j] = dp[i][k] + dp[k + 1][j] +node[i].r * node[k + 1 ].r * node[j].c; path[i][j] = k; } } } } cout<<"Case "<<++Case<<": "; Printf(0,n-1); puts(""); } return EXIT_SUCCESS; }
UVA 348 Optimal Array Multiplication Sequence 区间DP
原文:http://blog.csdn.net/yitiaodacaidog/article/details/19209961