Дана последовательность из n матриц заданных размеров [A1, A2, ..., An] (матрица Ai имеет размер pi-1 на pi ); требуется найти такую (полную) расстановку скобок в произведении A1A2 ... An, чтобы вычисление произведения требовало наименьшего числа умножений и найти результат перемножения этих матриц. [1, с.289].

    Комментарии вы можете посмотреть на шаге 7.

    Приведем текст программы:

Program Problem6_1; 
Uses srt;
Type{Тип:}
     matrix = array [1..10,1..10] of integer;{Перемножаемые матрицы}
     mix = array [1..10,1..10] of Longint; {Результат перемножения}
     mx = array [0..7] of byte;{Размерность матриц}
     ms = array [1..10,1..10] of byte; {Оптимальная расстановка скобок}
     MATR = array [1..7] of matrix; {Массив матриц}
     str1 = array [1..7] of string[50]; {Строка расстановки скобок}
Var
    U: matr; {Массив матриц}
    p: mx;{Размерность матриц}
    m: matrix;
    A: mix;
    R: str1;{Строка расстановки скобок}
    s: ms;{Оптимальная расстановка скобок}
    n,k,i,l,j: byte;
    H: string[8];
{---------- Процедура перемножения матриц ---------}
Procedure MATRIX_MULTIPLY(var C: mix; A,B: mix; cA,cB,rA,rB: byte);
Var i,j,k: byte;
Begin
  {Если число столбцов первой матрицы не равно числу строк второй матрицы} 
  If cA <> rB Then writeln('Перемножить нельзя!')
    else
       For i:= 1 To rA Do
         For j:= 1 To cB Do
           Begin
              C[i,j]:= 0;
              For k:= 1 To cA Do
                   C[i,j]:= C[i,j] + A[i,k]*B[k,j];
           end;
end;
{-- Процедура вычисления оптимальной стоимости премножения матриц --}
{---- и получение матрицы расстановки скобок в произведении матриц -----}
Procedure MATRIX_CHAIN_ORDER(var m:matrix; var s:ms; P:mx; n:byte);
Var i,j,l,k: byte;
    q: longint;
Begin
   For i:=1 To n Do m[i, i]:= 0;{Умножение матрицы на саму себя}
   For l:=2 To n Do {Количество матриц}
       For i:=1 To n-l+1 Do
         Begin
           j:= i + l - 1; {Сколько матриц перемножается}
           m[i,j]:= maxint;{Присваеваем максимально возможное значение}
           For k:=i To j-1 Do
             Begin
               {Вычисляем стоимость перемножения матриц}
               q:= m[i,k] + m[k+1,j] + p[i-1]*p[k]*p[j];
               If q < m[i,j] Then{Находим минимальную стоимость}
                                Begin
                                  m[i,j]:= q;
                                  s[i,j]:= k;{Расставление скобок}
                                end;
             end;
         end;
end;
{-- Процедура вычисления результата перемножения матриц --}
{-- и расстановка скобок в премножении матриц --}
Procedure MATRIX_CHAIN_MULTIPLY(var A:mix; var R:str1; U:matr; s:ms; i,j:byte);
Var k,l: byte;
    v,v1: string;
    x,y,C: mix;
Begin
   If j > i Then{Матрица не умножается сама на себя}
     Begin
        MATRIX_CHAIN_MULTIPLY(A, R, U, S, I, S[I,J]);
        X:= A;
        MATRIX_CHAIN_MULTIPLY(A, R, U, s, s[I,J]+1, j);
        Y:= A;
        MATRIX_MULTIPLY(C,X,Y,p[s[i,j]],p[j],p[i-1],p[s[i,j]]);
        {Перемножение матриц}
        {-------- Расстановка скобок --------------}
        If (R[s[i,j]]<>'') And (R[j]<>'') Then
        {Обе матрицы умножаются не в первый раз}
             Begin
               R[s[i,j]]:= R[s[i,j]] + R[j];
               R[j]:= R[s[i,j]];
             end
        else
         If (R[s[i,j]]='') And (R[j]<>'') Then
             Begin
               str(s[i,j],v);
               R[j]:= '(' + v + R[j] + ')';
               R[s[i,j]]:= R[j];
             end
         else
          If (R[j]='') And (R[s[i,j]]<>'') Then
          {Одна из матриц берется в первый раз}
             Begin
               str(j,v);
               R[s[i,j]]:= '(' + R[s[i,j]] + v + ')';
               R[j]:= R[s[i,j]];
             end
           else{Матрицы перемножаются в первый раз}
             Begin
               str(s[i,j],v);
               str(j,v1);
               R[s[i,j]]:= '(' + v + ' ' + v1 + ')';
               R[j]:= '(' + v + ' ' + v1 + ')';
             end;
     end
   else{Берется одна из первоначальных матриц}
     Begin
      For k:=1 To p[i-1] Do
       For l:=1 To p[j] Do
         C[k,l]:= U[i][k,l];
     end;
   A:= C;{Результат перемножения}
end;
{-------- Код основной программы -----------}
Begin
  clrscr;
  Repeat{Проверка}
   write(' Задайте число матриц (2..7):');
   readln(n);{Задание числа матриц}
  Until (n>1) And (n<=7);
  For i:=1 To n Do{Задание размерности матриц}
    Repeat
     If i=1 Then{Задание размерности первой матриц}
        Begin
          Repeat{Проверка}
           write('Задайте размерность ',i,' - й матрицы: ');
           read(p[i-1]);
           readln(p[i]);
          Until (p[i-1]>1) And (p[i-1]<=10);
        end
     else
        Begin
           write('Задайте размерность ',i,'- й матрицы: ',p[i-1],' ');
           readln(p[i]);
        end;
    Until (p[i]>1) And (p[i]<=10);
  randomize;
  {Заполнение матриц псевдослучайными числами  и вывод матриц на экран}
  For l:=1 To n Do
   Begin
    writeln(l,'-я матрица :');
    For i:=1 To p[l-1] Do
     Begin
      For j:=1 To p[l] Do
       Begin
         U[l][i,j]:= random(10);
         write(U[l][i,j],' ');
       end;
      writeln;
     end;
    writeln;
   end;
  MATRIX_CHAIN_ORDER(m,s,P,n);{Обращение к процедуре}
  Writeln('Наименьшая стоимость перемножения: ',m[1,n]);
  MATRIX_CHAIN_MULTIPLY(A,R,U,s,1,n);{Обращение к процедуре}
  writeln;
  writeln('Расстановка скобок: ',R[s[1,n]]);
  writeln;
  writeln('Полученный результат:');
  writeln;
  For i:=1 To p[0] Do{Вывод результата перемножения матриц на экран}
   Begin
    For j:=1 To p[n] Do
     Begin
       If (A[i,j]>=0) And (A[i,j]<=9) Then H:='        '
       {Для удобства просмотра матрицы}
        else If (A[i,j]>=10) And (A[i,j]<=99) Then H:='       '
         else If (A[i,j]>=100) And (A[i,j]<=999) Then H:='      '
          else If (A[i,j]>=1000) And (A[i,j]<=9999) Then H:='     '
            else If (A[i,j]>=10000) And (A[i,j]<=99999) Then H:='    '
             else If (A[i,j]>=100000) And (A[i,j]<=999999) Then H:='   '
              else If (A[i,j]>=1000000) And (A[i,j]<=9999999) Then H:='  '
               else H:=' ';
       write(A[i,j],H);
     end;
    writeln;
   end;
  readkey;
End.
Текст этой программы можно взять здесь.


(1)Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. — М.: МЦНМО, 2000.-960с.,263 ил.