zoukankan      html  css  js  c++  java
  • UVA 348 矩阵链乘

    UVA 348

    题意:

    给出 N 个矩阵(A1,A2,...,An),求完全括号化方案,使得计算乘积(A1A2...An)所需乘法次数最少。
    并输出方案。

    解题:

    算法导论是个好东西   讲的很详细~

    假设矩阵 A 和 B 相乘,那 A 的列数必须要和 B 的行数相同,
    即 若 A 的行列数为(x,y),则 B 须为(y,z), 它们相乘得到一个(x,z)的矩阵;需要乘 xyz 次。
    题目把相乘的顺序给出了,我们做的就是添加括号了。
    把所有矩阵用一个序列 P 表示,第 i 个矩阵的行列数为 P(i-1)和Pi

    求 N 个矩阵的完全括号化方案,
    当 N 为 1 时,只有一个矩阵,所以只有 1 种方案;
    当 N >= 2 时,可描述为两个已经完全括号化的部分积相乘的形式。
    设这个划分点在 k ;那么 A1..Ai..An = (A1..Ak)(Ak+1..An)
    然后同样的看 (1~k)(k+1 ~ N)这两段。
    用 m[i][j] 保存(i,j)这个区间括号化后可以得到的最小次数.
    于是 m[i][j] = m[i][k] + m[k+1][j] + P(i-1)PkPj;
    再用一个 数组记录 (i,j)这个区间的划分点在哪递归输出。
    我角的它就是个区间DP呀

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 110;
    const int INF = 0x3f3f3f3f;
    
    int p[maxn];
    int m[20][20],s[20][20];
    int x, n, cas = 1, cnt = 0;
    
    void print (int x, int y) {
        if(x == y) printf ("A%d",x);
        else {
            printf ("(");
            print (x, s[x][y]);
            if(s[x][y]) printf (" x ");
            print (s[x][y]+1, y);
            printf (")");
        }
    }
    int main()
    {
        while (scanf("%d",&n)!=EOF && n) {
            cnt = 0;
            scanf ("%d%d",&p[0], &p[1]);
            for (int i = 1; i < n; i ++) {
                scanf ("%d%d",&x,&p[i+1]);
            }
            for (int i = 1; i <= n; i ++) {
                for (int l=1, r; (r = l + i) <= n; l ++) {
                    m[l][r] = INF;
                    for (int k = l; k < r; k ++) {
                        int tmp = m[l][k] + m[k+1][r] + p[l-1] * p[k] * p[r];
                        if (tmp < m[l][r]) {
                            m[l][r] = tmp;
                            s[l][r] = k;
                        }
                    }
                }
            }
            printf ("Case %d: ",cas++);
            print (1, n);
            printf ("
    ");
        }
        return 0;
    }
  • 相关阅读:
    VC++6.0 自定义按钮,无标题对话框的拖动方法
    完整的使用线程池的多线程C/S Socket类
    树形控件Tree Control
    关闭数据执行保护
    VC++开发垃圾文件清理软件(下)
    用完成端口开发大响应规模的Winsock应用程序
    去掉右键多余显卡菜单
    自动登陆系统
    查询数据库中所有表名和表中所有字段名
    单行编辑框文本垂直居中(包含计算字体高度)
  • 原文地址:https://www.cnblogs.com/ember/p/5771140.html
Copyright © 2011-2022 走看看