В головоломку умножения играют с рядом карт, каждая из которых содержит одно положительное целое число. Во время хода игрок убирает одну карту из ряда и получает число очков, равное произведению числа на убранной карте и чисел на картах, лежащих непосредственно слева и справа от неё. Не разрешено убирать первую и последнюю карты ряда. После последнего хода в ряду остаётся только две карты.
    Цель игры - убрать карты в таком порядке, чтобы минимизировать общее количество набранных очков.
    Ограничения: 3 ≤ N ≤ 50, числа на картах целые от 1 до 50, время 1с. [1].

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

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

Program Problem6_6; 
Uses crt;
Var
   n,i,j: integer;
   v: array[1..50] of integer; {Числа на картах}
   b: array[1..50,1..50] of longint; {Минимальное количество очков}
{-- Рекурсивная функция поиска минимальго количества очков --}
Function func(p1,p2:integer):longint;
Var s,min:longint;
    i:integer;
Begin
    If b[p1,p2] >= 0 Then func:= b[p1,p2] {Не считает второй раз}
    else
      Begin
       If p2 = p1+1 Then b[p1,p2]:= 0{Если в последоватльности две карты}
       else
         Begin
          min:= maxlongint;{Максимальное значение}
          For i:= p1+1 To p2-1 do{Номера карт}
           Begin
             {поиск минимального значения(оптимального параметра)}
             s:= func(p1,i) + func(i,p2) + v[p1]*v[i]*v[p2];
             If s < min Then min:= s;
           end;
          b[p1,p2]:= min;{Заполнение матрицы B}
         end;
       func:= b[p1,p2];{Получение значения функции}
      end;
end;
{---- Код основной программы ----}
Begin
   clrscr;
   Repeat{Проверка данных на удовлетворение условию задачи}
    write('Введите количество карт (3..50): ');
    readln(n);
   Until (n >= 3) And (n <= 50);
   writeln('Введите числа на картах (1..50):');
   For i:=1 To n Do{Ввод чисел на картах}
     Repeat{Проверка}
      write(i,'- я карта :  ');
      readln(v[i]);
     Until (v[i] >= 1) And (v[i] <= 50);
   clrscr;
   writeln;
   write('Числа на картах: ');{Вывод введенных данных на экран}
   For i:=1 To n Do write(' ',v[i]);
   writeln;
   For i:=1 To n Do{«Обнуление» матрицы B}
     For j:=1 To n Do
         b[i,j]:= -1;
   writeln;{Обращение к функции и вывод полученного значения на экран}
   writeln('Минимальное количество очков:  ',func(1,n));
   readkey;
End.
Текст этой программы можно взять здесь.


(1)Меньшиков Ф.В. Олимпиадные задачи по программированию. - СПб: Питер, 2006. - 315с.