matrix chain multiplication

#include <iostream>
#include <vector>
using namespace std;

void print(vector<char> &vcname, vector<vector<int>> &virecord, int b, int e){//包含e
    if(b==e)
        cout<<vcname[b];
    else{
        /*
        cout<<"(";
        print (vcname, virecord, b, virecord [b] [e]);
        print (vcname, virecord, virecord [b] [e] + 1, e);
        cout<<")";
        */
        if(b<virecord[b][e]){
            cout<<"(";
            print (vcname, virecord, b, virecord [b] [e]);
            cout<<")";
        }
        else
            print (vcname, virecord, b, virecord [b] [e]);
        if(virecord[b][e]+1<e){
            cout<<"(";
            print (vcname, virecord, virecord [b] [e] + 1, e);
            cout<<")";
        }
        else
            print (vcname, virecord, virecord [b] [e] + 1, e);
    }
}

void method1(vector<pair<int,int>> vpii,vector<char> &vcname, vector<vector<int>> vvi){
    //method one:
    //This is equivalent to taking the step size as the limit. If the result before the current step size is known, then the optimal result under the current step size can be obtained based on the result of the previous step size.
    cout<<"method1: "<<endl;
    int n=vpii.size();
    vector<vector<int>> virecord;//Record the split point
    for(int i=0;i<n;i++)
        virecord.push_back(vector<int>(n,-1));
    for(int step=2;step<=n;step++){//Note the subscript here
        //When the current step size is calculated, the combination results smaller than this step size are calculated, that is, both vvi[i][k] and vvi[k+1][j] are known.
        for(int i=0;i<=n-step;i++){//当i=n-step时,j=i+step-1=n-1
            int j=i+step-1;//The current step size, the maximum matrix subscript at the current start i
            for(int k=i;k<j;k++){
                int itp=vvi[i][k]+vvi[k+1][j]+vpii[i].first*vpii[k].second*vpii[j].second;
                if(vvi[i][j]>itp){
                    vvi[i][j]=itp;
                    virecord[i][j]=k;//Record split information
                }
            }
            cout<<vvi[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<vvi[0][vpii.size()-1]<<endl;
    print(vcname,virecord,0,n-1);//Print matrix combination order
    cout<<endl;
}

void method2(vector<pair<int,int>> vpii,vector<char> &vcname, vector<vector<int>> vvi){
    //Method Two
    //The order of this structure is very clever
    //This is equivalent to a certain subscript as the limit. If the optimal result of the previous sequence has been obtained, then the optimal result up to the current subscript can be obtained based on the optimal result of the previous sequence.
    cout<<"method2: "<<endl;
    int n=vpii.size();
    vector<vector<int>> virecord;//Record the split point
    for(int i=0;i<n;i++)
        virecord.push_back(vector<int>(n,-1));
    for(int j=1;j<n;j++){//When j is calculated, k<j, vvi[i][k] has been calculated
        for(int i=j-1;i>=0;i--){//When i is calculated, k>i, vvi[k][j] has been calculated.
            for(int k=i;k<j;k++){
                int itp=vvi[i][k]+vvi[k+1][j]+vpii[i].first*vpii[k].second*vpii[j].second;
                if(itp<vvi[i][j]){
                    vvi[i][j]=itp;
                    virecord[i][j]=k;//Record split information
                }
            }
            cout<<vvi[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<vvi[0][vpii.size()-1]<<endl;
    print(vcname,virecord,0,n-1);//Print matrix combination order
    cout<<endl;
}

int main(){
    vector<pair<int,int>> vpii;
    vpii = {{30.35}, {35.15}, {15.5}, ​​{5.10}, {10.20}, {20.25}};
    vector<char> vcname;
    vcname={'A','B','C','D','E','F'};
    vector<vector<int>> vvi;
    for(int i=0;i<vpii.size();i++){
        vvi.push_back(vector<int>(vpii.size(),INT_MAX));
        vvi[i][i]=0;
    }
    method1(vpii,vcname,vvi);
    method2(vpii,vcname,vvi);
}
/*
http://blog.csdn.net/chenwenshi/article/details/6056015 It is said that methd2 is top-down, but I don't think it is.
 In fact, the two ideas are bottom-up. After all, dynamic programming depends on the optimal solution of the sub-problem, but the two methods divide the sub-problem differently.
 For the first method: it is equivalent to taking the step size as the limit. If the previous result of the current step size is known, then the optimal result under the current step size can be obtained according to the result of the previous step size.
 For the second method: it is equivalent to a certain subscript as the limit. If the optimal result of the previous sequence has been obtained, then the optimal result up to the current subscript can be obtained based on the optimal result of the previous sequence. .
*/

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325859392&siteId=291194637