UVA 442 - Matrix Chain Multiplication


http://blog.csdn.net/crazy__chen/article/details/38418199
Suppose you have to evaluate an expression like A*B*C*D*E where A,B,C,D and E are matrices. Since matrix multiplication is associative, the order in which multiplications are performed is arbitrary. However, the number of elementary multiplications needed strongly depends on the evaluation order you choose.

For example, let A be a 50*10 matrix, B a 10*20 matrix and C a 20*5 matrix. There are two different strategies to compute A*B*C, namely (A*B)*C and A*(B*C).
The first one takes 15000 elementary multiplications, but the second one only 3500.

Your job is to write a program that determines the number of elementary multiplications needed for a given evaluation strategy.

Input Specification

Input consists of two parts: a list of matrices and a list of expressions.
The first line of the input file contains one integer n ( tex2html_wrap_inline28 ), representing the number of matrices in the first part. The next n lines each contain one capital letter, specifying the name of the matrix, and two integers, specifying the number of rows and columns of the matrix.

The second part of the input file strictly adheres to the following syntax (given in EBNF):

SecondPart = Line { Line } <EOF>
Line       = Expression <CR>
Expression = Matrix | "(" Expression Expression ")"
Matrix     = "A" | "B" | "C" | ... | "X" | "Y" | "Z"

Output Specification

For each expression found in the second part of the input file, print one line containing the word "error" if evaluation of the expression leads to an error due to non-matching matrices. Otherwise print one line containing the number of elementary multiplications needed to evaluate the expression in the way specified by the parentheses.

Sample Input


9
A 50 10
B 10 20
C 20 5
D 30 35
E 35 15
F 15 5
G 5 10
H 10 20
I 20 25
A
B
C
(AA)
(AB)
(AC)
(A(BC))
((AB)C)
(((((DE)F)G)H)I)
(D(E(F(G(HI)))))
((D(EF))((GH)I))

Sample Output


0
0
0
error
10000
error
3500
15000
40500
47500
15125

题目描述:输入n个矩阵的维度和一个矩阵链乘的表达式,输出乘法的次数,如果乘法无法进行,则输出error。

根据题意,矩阵我定义为一个有rol,row两个属性的对象,我们手动输入一系列的矩阵
然后输入矩阵链乘表达式,其中表达式内可能有括号,所以括号内的要想相乘,否则应该从左向右乘(矩阵相乘是不符合交换律的)

使用栈来解决,第一个站用于存储矩阵,一个栈用于存储左括号的位置
顺序扫描矩阵链乘表达式,遇到矩阵(也就是非括号,程序里面我直接用矩阵在数组中的下标表示),将其装入矩阵栈。遇到左括号,将遇到左括号的位置,装入括号栈。遇到右括号,我们从括号栈里面记录的最后一个左括号的位置开始,将矩阵连乘,一直到右括号为止。
乘的过程中,如果出现不能相乘,结束程序;如果连乘结束,将结果矩阵装入矩阵栈(注意将矩阵栈中,刚才连乘的矩阵全部清空)
上述过程后,矩阵栈中,是一系列可以直接顺序链乘的矩阵,连乘之,同样,如果出现不能相乘,结束程序;否则等到最后的矩阵结果


public class Matrix {
 int col = 0;
 int row = 0;
 public Matrix(int col,int row) {
  this.col = col;//列
  this.row = row;//行
 }  
}

public class Test {    
    //矩阵相乘,返回新矩阵
    public static Matrix multiply(Matrix a , Matrix b )  {  
        return new Matrix( a.col,b.row);         
    }  
    
    public static boolean can_mul(Matrix a , Matrix b )  {  
        if( a.row == b.col ) return true ;  
        return false ;  
    }  
    
    public static void main(String[] args) {
        int total = 4;//矩阵数目
        Matrix[] matrixs = new Matrix[total];
        matrixs[0] = new Matrix(3,3);
        matrixs[1] = new Matrix(3,4);
        matrixs[2] = new Matrix(4,5);
        matrixs[3] = new Matrix(5,6);
        
        String[] str= {"0","(","1","2",")","3"};//乘法表达式
        Matrix[] stack = new Matrix[str.length];//矩阵栈
        int[] left = new int[str.length];//括号栈,用于存放左括号的位置
        
        int stackLen = 0;//用于记录矩阵栈的末端
        int mL = 0;//mL+1=矩阵进入栈的数目
        //一个m×n的矩阵a(m,n)左乘一个n×p的矩阵b(n,p),会得到一个m×p的矩阵c(m,p)
        for(int i=0,j=0,k=0;i<str.length;i++){
            if(str[i] == "("){//如果是左括号,进入括号栈
                left[j] = stackLen;//记录栈中左括号应在矩阵栈的位置                
                j++;
            }else if(str[i] == ")"){//如果是右括号                            
                Matrix tmp = stack[left[j-1]];//遇到右括号前,最后一次记录左括号右边的第一个矩阵
                for(int m=left[j-1]+1;m<stackLen;m++){//将左右括号内的矩阵相乘
                    if(can_mul(tmp, stack[m])){//如果能相乘
                        tmp = multiply(tmp, stack[m]);
                    }else{//如果不能相乘,结束程序
                        System.out.println("error");
                        System.exit(-1);
                    }
                }
                stack[left[j-1]] = tmp;//将新矩阵放入栈
                
                stackLen = left[j-1]+1;//将矩阵栈从新矩阵开始继续计数                
                for(int n=stackLen;n<stack.length;n++){//将后面的矩阵清空
                    stack[n] = null;
                }
                j--;//将括号栈内,最后一个左括号去掉
                
            }else{//如果是矩阵,进入矩阵栈
                stack[stackLen] = matrixs[mL];
                System.out.println(stack[stackLen].row);
                stackLen++;            
                mL++;
            }
        }

        Matrix tmp = stack[0];        
        for(int i = 1;i<stackLen;i++){//顺序计算矩阵相乘
            if(can_mul(tmp, stack[i])){
                tmp = multiply(tmp, stack[i]);
            }else{
                System.out.println("error");
                System.exit(-1);
            }
        }
        
        System.out.println("结果为row="+tmp.row+",col="+tmp.col+"的矩阵");
    }
}

比如(((((DE)F)G)H)I),遇到 (就cnt累计加一,字母入栈,遇到)减一,并出栈两个矩阵计算运算量,将计算后的矩阵压入栈。当cnt等于0时就输出运算量。
  1. int sum,n;  
  2. int mat[30][2];  
  3. int arr[30],prev[30], next[30];  
  4. char str[1000];  
  5.   
  6. void solve(){  
  7.     // 如过只有一个矩阵,那么直接输出结果0  
  8.     if(strlen(str)==1 && isupper(str[0])){  
  9.         printf("0\n");  
  10.     }  
  11.     else{  
  12.         char copyMat[30][2];  
  13.         int i,j;  
  14.         // 复制一个数组进行操作。 因为后面的操作需要对这些矩阵进行修改  
  15.         for(i=0; i<n; ++i){  
  16.             copyMat[i][0] = mat[i][0];  
  17.             copyMat[i][1] = mat[i][1];  
  18.         }  
  19.         sum=0;  
  20.         stack<char>st;   
  21.           
  22.         for(i=0; i<strlen(str); ++i){  
  23.             if(str[i]=='(' || isupper(str[i]))  
  24.                 st.push(str[i]);  
  25.             else if(str[i]==')'){  
  26.                 stack<char>temp;        
  27.         // 当碰到‘)’时,把栈中的矩阵全都取出来进行计算     
  28.                 while(isupper(st.top())){  
  29.                     temp.push(st.top());              
  30.                     st.pop();  
  31.                 }  
  32.                 // 把'('也弹出  
  33.                 st.pop();  
  34.                 char ex;  
  35.                 // 取出第一个矩阵(在原表达式中是最左边的一个)  
  36.                 if(!temp.empty()){  
  37.                     ex=temp.top();  
  38.                     temp.pop();  
  39.                 }  
  40.                 while(!temp.empty()){  
  41.                     char multi = temp.top();  
  42.                     temp.pop();  
  43.                     // 如果左边矩阵的列数和右边矩阵的函数不同,则直接输出 error  
  44.                     if(copyMat[ex-'A'][1] != copyMat[multi-'A'][0]){  
  45.                         printf("error\n");  
  46.                         return ;  
  47.                     }  
  48.                     // 计算相乘次数,加上  
  49.                     sum += copyMat[ex-'A'][0]*copyMat[multi-'A'][0]*copyMat[multi-'A'][1];  
  50.                     // 相乘后得到一个新矩阵,更新尺寸  
  51.                     copyMat[ex-'A'][1] = copyMat[multi-'A'][1];  
  52.                 }  
  53.                 st.push(ex);  
  54.             }  
  55.         }    
  56.         printf("%d\n",sum);  
  57.     }  
  58. }  
  59.   
  60.   
  61. int main()  
  62. {  
  63.     freopen("input.txt""r",stdin);  
  64.     char ch;  
  65.     int  i, j;  
  66.     scanf("%d%*c", &n);  
  67.     for(i=0; i<n; ++i){  
  68.         scanf("%c %d %d%*c",&ch,&mat[i][0],&mat[i][1]);  
  69.     }  
  70.       
  71.     while(gets(str)){  
  72.         solve();  
  73.     }  
  74.     return 0;  

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts