描述
矩阵乘法的运算量与矩阵乘法的顺序强相关。
例如:A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵
计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。
编写程序计算不同的计算顺序需要进行的乘法次数。
数据范围:矩阵个数:1≤n≤15 ,行列数:1≤rowi,coli≤100 ,保证给出的字符串表示的计算顺序唯一。
进阶:时间复杂度:O(n) ,空间复杂度:O(n)
输入描述:
输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则
计算的法则为一个字符串,仅由左右括号和大写字母('A'~'Z')组成,保证括号是匹配的且输入合法!输出描述:
输出需要进行的乘法次数
示例1
输入:
3 50 10 10 20 20 5 (A(BC))输出:
3500
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int a = in.nextInt();
Map<Character, Obj> map = new HashMap<>();
char start = 'A';
for (int i=0; i<a; i++) {
int n1 = 0;
if (in.hasNextInt()) {
n1 = in.nextInt();
}
int n2 = 0;
if (in.hasNextInt()) {
n2 = in.nextInt();
}
map.put((char)(start+i), Obj.build(n1, n2, 0));
}
String b = "";
while (in.hasNextLine()) {
b = in.nextLine();
};
int res = getRes(b.toCharArray(), map);
System.out.println(res);
}
}
public static int getRes(char[] chs, Map<Character, Obj> map) {
Stack<Character> stack = new Stack<>();
Stack<Character> dataStack = new Stack<>();
int len = chs.length;
int sum = 0;
char index = 'a';
for (int i=0; i<len; i++) {
char ch = chs[i];
if (ch == '(') {
stack.add(ch);
}
else if (ch == ')') {
Queue<Character> queue = new LinkedList<>();
while (stack.peek()!='(') {
queue.add(stack.pop());
}
if (stack.peek()=='(') {
stack.pop();
}
char ch1 = queue.poll();
Obj tmp = null;
while (queue.peek() != null) {
char chT = queue.poll();
Obj oT = map.get(chT);
if (tmp == null) {
tmp = oT.compute(map.get(ch1));
}
else {
tmp = oT.compute(tmp);
}
}
if (tmp != null) {
stack.add(index);
map.put(index, tmp);
index++;
}
else {
stack.add(ch1);
}
}
else {
if (stack.peek() == '(') {
stack.add(ch);
}
else {
Obj tmp = null;
if (stack.peek() != null) {
char chT = stack.pop();
Obj oT = map.get(chT);
tmp = oT.compute(map.get(ch));
stack.add(index);
map.put(index, tmp);
index++;
}
}
}
}
if (!stack.isEmpty()) {
char ch = stack.peek();
if (ch!='(') {
Obj o = map.get(ch);
return o.val;
}
}
return 0;
}
public static class Obj {
int r; // 行
int c; // 列
int val; // 乘积存取
public static Obj build(int r, int c, int val) {
Obj o = new Obj();
o.r = r;
o.c = c;
o.val = val;
return o;
}
public Obj compute(Obj o) {
int val = r*o.c * c;
Obj o1 = new Obj();
o1.r = r;
o1.c = o.c;
o1.val = val + this.val + o.val;
return o1;
}
}
}