题解 | #矩阵乘法计算量估算#

矩阵乘法计算量估算

https://www.nowcoder.com/practice/15e41630514445719a942e004edc0a5b?tpId=37&&tqId=21293&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题意:

        A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵

        计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。

        编写程序计算不同的计算顺序需要进行的乘法次数。


方法一:

思路:
        栈存储矩阵的行和列。
        遍历字符串:
                                如果是字符,则直接入栈;
                               如果是右括号,则栈弹出两个元素,并累加乘法次数,再形成新的矩阵并入栈。
      在这过程并累加乘法次数,最后输出乘法次数。



#include <bits/stdc++.h>

using namespace std;
int a[20][2];
string s;

int main(){
    int n;
    while(cin >> n){
        for(int i=0;i<n;i++)
            cin >> a[i][0] >> a[i][1];//输入矩阵的行列
        cin >>s;
        stack<pair<int,int>> st;//栈存储矩阵的行列
        int len=s.size();
        int res=0;
        for(int i=0;i<len;i++){//遍历字符串
            if(s[i]==')'){//如果是右括号,则栈弹出两个元素,并累加乘法次数
                auto y=st.top();
                st.pop();
                auto x=st.top();
                st.pop();
                if(x.second==y.first){
                    res+=x.second*x.first*y.second;
                    st.push({x.first,y.second});//形成新的矩阵并入栈
                }else if(x.first==y.second){
                    res+=x.first*x.second*y.first;
                    st.push({x.second,y.first});
                }
                
            }else if(s[i]!='('){//如果是字符,则直接入栈
                int t=s[i]-'A';
                st.push({a[t][0],a[t][1]});
            }
        }
        cout << res << endl;//输出答案
    }
    
    return 0;
}


时间复杂度:
空间复杂度:

方法二
递归

思路:
        通过递归找到左右边界点。
        规则:
                遍历给定字符串的 l , r 区间,如果找到左括号,则循环找到匹配的右括号,并递归下去。
                最后,计算两个矩阵的值赋给全局变量res,并且生成新的矩阵。


#include <bits/stdc++.h>

using namespace std;
int a[20][2];
string s;
int res=0,n;

//递归
pair<int,int> f(int l,int r){

    stack<pair<int,int>> st;
    for(int i=l;i<=r;i++){
        if(s[i]=='('){
            int j=i+1;
            int level=1;
            while(j<=r){//循环找到匹配的右括号
                if(s[j]=='('){
                    level++;
                }else if(s[j]==')'){
                    level--;
                    if(level==0){
                        auto t=f(i+1,j-1);//递归
                        st.push(t);//后序入栈
                        break;
                    }
                }
                j++;
            }
            i=j;
        }else if(isalpha(s[i])){
            int x=s[i]-'A';
            st.push({a[x][0],a[x][1]});
        }
    }
    auto t2=st.top();
    st.pop();
    auto t1=st.top();
    st.pop();
    res+=t1.first*t1.second*t2.second;//构造新的矩阵
    return {t1.first,t2.second};
}

int main(){
    while(cin >> n){
        res=0;
        for(int i=0;i<n;i++)
            cin >> a[i][0] >> a[i][1];//输入矩阵的行列
        cin >>s;
        f(1,s.size()-2);//递归
        cout << res << endl;//输出答案
    }
    
    return 0;
}

时间复杂度:
空间复杂度:







全部评论
方法一里面 if(x.second==y.first){} else if(x.first==y.second){} 这里不需要判断,只需要注意矩阵前后的相乘顺序,先出来的为y,后pop出来的为x,相乘顺序为x*y
2 回复 分享
发布于 2023-04-15 19:52 浙江
方法一里面 if(x.second==y.first){} else if(x.first==y.second){} 这里不需要判断啊,矩阵相乘前提就是x.second==y.first
2 回复 分享
发布于 2022-04-05 20:17
这题这解法一看就有问题,三个矩阵连乘肯定不对
1 回复 分享
发布于 2022-09-07 17:12 广东
矩阵乘法是满足结合率的,如果BCD,那么答案可以先计算BC,也可以先计算CD,所以必须每两个矩阵都需要加括号来确保计算次序唯一
点赞 回复 分享
发布于 05-04 20:21 辽宁
这个方法不行啊,如果出现A(BCD)就不行啊
点赞 回复 分享
发布于 01-14 22:39 湖南
这题只要最后按照输入的估算出计算量输出不就行了吗?
点赞 回复 分享
发布于 2022-06-15 18:31
方法一小括号内元素有三个就不对吧?求大佬解答
点赞 回复 分享
发布于 2022-05-31 12:06

相关推荐

11-03 13:18
门头沟学院 Java
包行:平时怎么刷算法题的哇,字节的手撕听说都很难
字节跳动工作体验
点赞 评论 收藏
分享
评论
12
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务