动态规划动态规划

(7) 动态规划(下) 矩阵链乘与OBST树

2016-11-03  本文已影响0人  陈码工

矩阵链乘问题

问题描述:
如何实现对A1·A2·A3...An个矩阵链乘的打括号(分割), 使得其乘法次数m是最少的?
已知: A[x,y] B[y,z] 两个矩阵相乘, 消耗的乘法次数是x · y · z次;

/*Matrix-Chain-Order*/
//@p: 从p[0]~p[n], 代表A[1]~A[n]矩阵的行数和列数;
//其中, A[1]为p[0]xp[1]规模, A[x]为p[x-1]p[x]规模
Matrix-Chain-Order(int p[])
n = p.length-1;
let m[1~n][1~n] and s[1~n][1~n] be new arrays;
for (i = 1~n)
    m[i][i] = 0;  //m[i][i] 其实就是A[i]自己一个p[i-1]*p[i]规模的矩阵, 类似于递归树的T(1)根部情形;
for (l = 2 ~ n)  // l: length
    for (i = 1 ~ n-l+1)  //i: head of a block;
        j = i+l-1;  //j: end of a block;
        m[i][j] = 9999;  //放一个无穷大值, 等着被替换;
        for (k = i ~ k-1)  //k: 代表砍下分割成两个block的位置, 注意是在A[k]矩阵的右侧分开来;
            q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]
            if (q <= m[i][j])
                m[i][j] = q;
                s[i][j] = k; //记录分割位置;
return m, s arrays;

时间复杂度: 有三层for循环, 所以T(n) = Θ(n^3)

最优二分搜索树

问题描述: a[1]~a[n]的关键字, 已知出现概率为p[1]~p[n], 另外落入a[i]两侧间隙的概率是q[0]~q[n], 求最小比较次数e和OBST的构成; 其中q[i]代表是落入(i, i+1)区间的概率

/*Optimal-Binary-Search-Tree*/
//@p: p[n]存放着a[1]~a[n]关键词出现的概率
//@q: q[n+1]存放着q[0]~q[n]的落入缺失区间的概率
//即q[i]是落入(a[i],a[i+1]) 开区间的概率
Optimal-BST(p[], q[], n)
let e[1~n+1][0~n], w[1~n+1][0~n], root[1~n][1~n] be new arrays;
for (i = 1~n+1)
    e[i][i-1] = q[i-1];  //边界情况, 覆盖了落入小于a[i]的情形
    w[i][i-1] = q[i-1]; 
for (l = 1~n)
    for (i = 1~n-l+1)    //i是头部
        j = i+l-1;  //j是尾部
        e[i][j] = 9999;  //让e[i][j]无穷大
        w[i][j] = w[i][j-1] + p[j] + q[j]
        for (k = i~j)
            t = e[i, k-1] + e[k+1, j] + w[i][j];
            if (t<=e[i][j])
                e[i][j] = t;
                root[i][j] = k;
return e, root arrays;

时间复杂度: 因为有三层for循环, 所以T(n)=Θ(n^3);

上一篇 下一篇

猜你喜欢

热点阅读