SHUOJ 1611 矩阵连乘问题(dp)

来源:互联网 发布:linux grub引导win7 编辑:程序博客网 时间:2024/05/18 19:42

矩阵连乘问题

Description

给定n个矩阵A1,A2,…,An,其中,Ai与Aj+1是可乘的,i=1,2,…,n-1。

你的任务是要确定矩阵连乘的运算次序,使计算这n个矩阵的连乘积A1A2…An时总的元素乘法次数达到最少。

例如:3个矩阵A1,A2,A3,阶分别为10×100、100×5、5×50,计算连乘积A1A2A3时按(A1A2)A3所需的元素乘法次数达到最少,为7500次。

Input

测试数据有若干组,每组测试数据有2行。

每组测试数据的第1行是一个整数n,(0<n<20),第2行是n+1个正整数p0、p1、p2、…、pn,这些整数不超过100,相邻两个整数之间空一格,他们表示n个矩阵A1,A2,…,An,的阶pi-1´pi,i=1,2,…,n。

输入直到文件结束。

Output

对输入中的每组测试数据,输出2行。先在一行上输出“Case #”,其中“#”是测试数据的组号(从1开始),再在第2行上输出计算这n个矩阵的连乘积A1A2…An时最少的总的元素乘法次数,再空一格,接着在同一行上输出矩阵连乘的添括号形式。

注意:最外层括号应去掉。

Sample Input

310 100 5 50450 10 40 30 5

Sample Output

Case 17500 (A1A2)A3Case 210500 A1(A2(A3A4))


题解:

现在的我果然还只是个蒟蒻,dp一片混沌。。希望半年后我回头看时能豁然开朗吧0.0
强推http://m.blog.csdn.net/article/details?id=8030012
dp最重要的是递推关系,递推关系如下:
对不起这个公式我是推不出来的。。我照着别人的公式推还推了半天。。
那么跨过了dp递推公式的难关,这个题还有一个难点是如何打印括号,
这里是使用递推进行括号匹配的。
(注意如果大于一个矩阵的话,递推公式会把最前面和最后面的括号也打出来,不符合题意,需要自己删除)
附上渣渣调了半天才过的AC Code:
import java.io.*;import java.util.*;public class Main {static int shu[];static int dp[][];static int jl[][];static int n;static StringBuilder s;public static void main(String[] args) {Scanner sc=new Scanner(System.in);int r=0;while(sc.hasNext()){r++;System.out.println("Case "+r);n=sc.nextInt();s=new StringBuilder();int k=n+1;dp=new int[n+1][n+1];jl=new int[n+1][n+1];shu=new int[k];for(int i=0;i<k;i++){shu[i]=sc.nextInt();}dp();/*System.out.println(n);for(int i=0;i<n+1;i++){for(int j=0;j<n+1;j++){System.out.print(dp[i][j]);}System.out.println('\n');}*/printBrackets(1,n);//根据jl矩阵递归将括号结果保存在s中System.out.print(dp[1][n]+" ");//判断不是只有一个矩阵if(s.charAt(0)=='('){s.deleteCharAt(0);s.deleteCharAt(s.length()-1);}System.out.println(s);}}   static void dp(){   int j;   for(int l=2;l<=n;l++){// 枚举矩阵链长度   for(int i=1;i<=n-l+1;i++){//  枚举矩阵链的起点   j=i+l-1;   dp[i][j]=Integer.MAX_VALUE;   for(int k=i;k<=j-1;k++){  //枚举断点   int cur=dp[i][k]+dp[k+1][j]+shu[i-1]*shu[k]*shu[j];//递推   if(cur<dp[i][j]){   dp[i][j]=cur;   jl[i][j]=k;   }   }   }   }   }   static void printBrackets(int i,int j){   if(i==j){   s.append("A"+i);   }   else{   s.append("(");   printBrackets(i,jl[i][j]);   printBrackets(jl[i][j]+1,j);   s.append(")");   }   }}


0 0
原创粉丝点击