算法作业——最优矩阵连乘

最优矩阵连乘的递推写法,备忘录写法,及其用一个二维数组保存最优结果,然后递归打印。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 100;
const int inf = 0x3f3f3f3f;


int s[maxn][maxn];
struct Mart {
    int h, w;
}mart[maxn];

int get_ans(int n, int d[][maxn], int *p) {
    for(int i = 0; i <= n; i++) d[i][i] = 0;
    for(int len = 2; len <= n; len++) {
        for(int i = 1; i <= n; i++) {
            int j = i + len - 1;
            if(j > n) break;
            d[i][j] = inf;

            for(int k = i; k < j; k++) {
//                d[i][j] = min(d[i][j], d[i][k] + d[k+1][j] + p[i-1]*p[k]*p[j]);
                if(d[i][j] > d[i][k] + d[k+1][j] + p[i-1]*p[k]*p[j]) {
                    d[i][j] = d[i][k] + d[k+1][j] + p[i-1]*p[k]*p[j];
                    s[i][j] = k;
                }
            }
        }
    }
    return d[1][n];
}
int get_Ans(int l, int r, int d[][maxn], int *p) {
    if(~d[l][r]) return d[l][r];
    if(l == r) return d[l][r] = 0;
    d[l][r] = inf;
    for(int k = l; k < r; k++) {
//        d[l][r] = min(d[l][r], get_Ans(l, k, d, p) + get_Ans(k+1, r, d, p) + p[l-1] * p[k] * p[r]);
        if(d[l][r] > get_Ans(l, k, d, p) + get_Ans(k+1, r, d, p) + p[l-1] * p[k] * p[r]) {
            d[l][r] = get_Ans(l, k, d, p) + get_Ans(k+1, r, d, p) + p[l-1] * p[k] * p[r];
            s[l][r] = k;
        }
    }
    return d[l][r];
}

void print_ans(int l, int r) {
    if(l == r) {
        printf("A%d", l);
        return ;
    }
    int k = s[l][r];
    printf("(");
    print_ans(l, k);
    print_ans(k+1, r);
    printf(")");
}

int main()
{
//    freopen("i.txt", "r", stdin);
    int d[maxn][maxn],p[maxn];
    int n;
    scanf("%d", &n);  // 输入矩阵的个数
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &mart[i].h, &mart[i].w);  // 矩阵的高and宽
    }
    for(int i = 0; i <= n; i++) {
        if(i == 0) {
            p[i] = mart[i+1].h;
        }
        else p[i] = mart[i].w;
    }
    printf("动态规划方法 ans = %d\n", get_ans(n, d, p));
    print_ans(1, n);
    putchar('\n');
    memset(d, -1, sizeof(d));
    printf("-------------------------------------------\n");
    printf("备忘录方法   ans = %d\n", get_Ans(1, n, d, p));
    print_ans(1, n);
    putchar('\n');
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunmaoxiang/article/details/88873493