算法导论——动态规划——矩阵链乘法

给定n个矩阵A[n],其中A[i]的维数用数组MATRIX[i]×MATRIX[i+1]表示,记为数组MATRIX[n+1]。

源代码:

#include<stdio.h>
#include<stdlib.h>
#include<iostream>

using namespace std;

int const N = 100;
int MATRIX[N] = { NULL,30,35,15,5,10,20,25 };//记录矩阵的维数表示

int m[N][N]; //记录链乘的最小代价
int c[N][N]; //记录分割的位置

struct BRACKET {   //记录括号情况
    int left=0;            //左括号
    int right=0;        //右括号
}b[N];
int  stack[N];  //将分割位置入栈,
int s=0;  //栈计数;

int main() {
    int n;                            //记录维数个数,矩阵数为n-1
    int i,j;
    int low, high;
    int len; 
    n = 7;
/*    cin >> n;                                //可以输入n 用n个随机数来测试
    for (i = 1; i <= n; i++) {
        MATRIX[i] = (rand()%5+1);
        cout <<"MATRIX["<<i<<"]="<<MATRIX[i] <<"\n";
    }*/
    for (i = 1; i <= n; i++)                //初始化m
        for (j = 1; j <= n; j++)
            m[i][j] = 0;

    for (len=1;len<n-1;len++){                        //len是low和high 之间的间隔
        for (low = 1,high=2; high < n-1; low++) {
            high = low + len;
            m[low][high] = 999999;                    //必须在此处将m正无穷,用于比较
            for (i = low; i < high; i++) {
                int temp = m[low][i] + m[i+1][high] + MATRIX[low] * MATRIX[i+1] * MATRIX[high+1];
                if (m[low][high] > temp) {
                    m[low][high] = temp;
                    c[low][high] = i;
                    stack[s] = i;                //入栈,用于计算括号的位置

                }
            }
            s++;
        }

    }

/*    for (i = 1; i < n; i++) {                        //打印m
        for (j = i; j < n; j++)
            cout << m[i][j] << "\t ";
        cout << endl;
    }

    for (i = 1; i < n; i++) {                        //打印c
        for (j = i; j < n; j++)
            cout << c[i][j] << " ";
        cout << endl;
    }

    for (i = 0; i < s; i++)                            //打印栈
        cout << stack[i] << " ";
    cout << endl;*/


    for (i = s - 1; i >= 0; i--) {                    //寻找括号的位置
        int k = stack[i];
        if (b[k].left || b[k].right) continue;
        for (int i = 2; ; i++) {                //向左索引    
            if (k - 2 < 0 ||b[k-1].left) break;
            if (k - i <= 0) {
                b[0].left++;
                b[k].right++;
                break;
            }
            if (b[k - i].left) {
                b[k - i].left++;
                b[k].right++;
                break;
            }
        }
        for (int i = 2; ; i++) {                //向右索引
            if (n - 1 < k + 2||b[k+1].right) break;
            if (k + i >= n-1) {
                b[n-1].right++;
                b[k].left++;
                break;
            }
            if (b[k + i].right) {
                b[k + i].right++;
                b[k].left++;
                break;
            }
        }
    }


    for (i = 0; i < n; i++) {            //打印表达式
        while (b[i].right) {
            cout << ")";
            b[i].right--;
        }
        while (b[i].left) {
            cout << "(";
            b[i].left--;
        }
        if (i + 1 == n) break;
        cout<<" " << "A" << i+1<<" ";

    }

    return 0;
}

测试用例:

输出结果:

猜你喜欢

转载自www.cnblogs.com/hwaa/p/10908442.html