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 ("\n");
    }
    return 0;
}
时间: 2024-12-25 19:40:11

UVA 348 矩阵链乘的相关文章

UVa 442 矩阵链乘及scanf说明符中的\n

题目:计算题给矩阵相乘次序所需的相乘次数.   我们已知的m*n和n*k矩阵相乘,得到的是m*k矩阵,但需要的相乘次数是m*n*k(开始当成了m*k %>_<%).evaluate,求值 思路:每个矩阵用结构体表示,有名字.行.列.需要计算的次数.矩阵相乘的过程用栈来模拟.遇到左括号(,压栈这是自然的.遇到一个矩阵时,检查栈顶,如果栈顶元素是左括号,则压栈,否则就是矩阵,则比较栈顶矩阵和输入矩阵是否匹配,如果匹配则修改栈顶矩阵的列.计算次数,这样输入矩阵对栈顶进行了修改,相当于完成了相乘,这时

UVa 442 矩阵链乘

Input Specification Input consists of two parts: a list of matrices and a list of expressions. The first line of the input file contains one integer n (  ), representing the number of matrices in the first part. The next n lines each contain one capi

UVA 348 Optimal Array Multiplication Sequence(最优矩阵链乘)

L - Optimal Array Multiplication Sequence Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 348 Appoint description:  acmparand  (2013-08-02)System Crawler  (2015-08-04) Description Given two arrays A a

UVA 348 &amp; ZOJ 1276 Optimal Array Multiplication Sequence(dp , 矩阵链相乘问题)

Optimal Array Multiplication Sequence Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Given two arrays A and B, we can determine the array C = AB using the standard definition of matrix multiplication: The number of

UVa 442 Matrix Chain Multiplication(矩阵链乘,模拟栈)

题意  计算给定矩阵链乘表达式需要计算的次数  当前一个矩阵的列数等于后一个矩阵的行数时  他们才可以相乘  不合法输出error 输入是严格合法的  即使只有两个相乘也会用括号括起来  而且括号里最多有两个 那么就很简单了 遇到字母直接入栈  遇到反括号计算后入栈  然后就得到结果了 #include<cstdio> #include<cctype> #include<cstring> using namespace std; const int N = 1000;

uva348Optimal Array Multiplication Sequence (最优矩阵链乘+路径输出)

Optimal Array Multiplication Sequence Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Practice UVA 348 Appoint description: Description Download as PDF Given two arrays A and B, we can determine the array C = AB using the

矩阵链乘(Matrix Chain Multiplication)

输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数.如果乘法无法进行,则输出error.假定A是m*n矩阵,B是n*p矩阵,那么A*B是m*p矩阵,乘法次数为m*n*p.如果A的列数不等于B的行数,则乘法无法进行. 例如,A是50*10的,B是10*20的,C是20*5的,则(A(BC))的乘法次数为10*20*5(BC的乘法次数) +50*10*5(A(BC)的乘法次数) = 3500. #include<cstdio> #include<stack> #include<

矩阵链乘

矩阵链乘之结构体构造函数 struct构造函数,和构造函数的重载函数长这个样子,和C++的构造函数差不过. struct Dog { Dog() { name = "wangwang"; age = 10; } string name; int age; }; struct Dog { Dog() { name = "Ao di"; age = 2; } Dog(string n) { name = n; age = 10; } Car(string n, int

POJ 0016 20603矩阵链乘

传送门:http://oj.cnuschool.org.cn/oj/home/solution.htm?solutionID=35454 20603矩阵链乘 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 输入n个矩阵的维度和一些矩阵链乘的表达式,输出乘法的次数.如果乘法无法进行,输出error.假定A是m*n矩阵,B是n*p矩阵,则乘法的次数为m*n*p.如果矩阵A的列数不等于矩阵B的行数,则这两个矩阵无法进行乘法运算.例