Разбор
Пусть — минимальная стоимость, за которую можно свести массив до одного элемента. Это значение будем хранить в ячейке .
Очевидно, что .
Из условия задачи следует, что
Вычислим значение . Объединение трех чисел в одно можно совершить двумя способами:
Объединить и за , после чего объединить и за .
Объединить и за , после чего объединить и за .
Таким образом
Теперь рассмотрим вычисление значения . Для преобразования массива в один элемент, который будет равен , следует выбрать некоторое значение , рекурсивно решить задачу для массивов и , после чего объединить элементы и . Значение следует выбрать таким образом, чтобы стоимость преобразования была минимальной:
Для быстрых вычислений сумм воспользуемся массивом префиксных сумм , в котором
откуда .
Реализация алгоритма
Объявим рабочие массивы.
#define MAX 101 #define INF 0x3F3F3F3F int dp[MAX][MAX], a[MAX], pref[MAX];
Функция возвращает минимальную стоимость, за которую можно преобразовать массив к одному элементу.
int f(int i, int j) { if (dp[i][j] == INF) for (int p = i; p < j; p++) dp[i][j] = min(dp[i][j], f(i, p) + f(p + 1, j) + (pref[j] - pref[i - 1]) * k); return dp[i][j]; }
Основная часть программы. Читаем входные данные.
scanf("%d %d", &n, &k); memset(dp, 0x3F, sizeof(dp)); for (i = 1; i <= n; i++) { scanf("%d", &a[i]); dp[i][i] = 0;
Вычисляем массив префиксных сумм.
pref[i] = pref[i - 1] + a[i]; }
Вычисляем и выводим ответ.
printf("%d\n", f(1, n));
Python реализация
Объявим константу бесконечность.
INF = float('inf')
Функция возвращает минимальную стоимость, за которую можно преобразовать массив к одному элементу.
def f(i, j): if dp[i][j] == INF: for p in range(i, j): dp[i][j] = min(dp[i][j], f(i, p) + f(p + 1, j) + (pref[j] - pref[i - 1]) * k) return dp[i][j]
Основная часть программы. Читаем входные данные.
n, k = map(int, input().split()) a = [0] + list(map(int, input().split()))
Вычисляем массив префиксных сумм.
pref = [0] * (n + 1) for i in range(1, n + 1): pref[i] = pref[i - 1] + a[i]
Инициализируем массив .
dp = [[INF] * (n + 1) for _ in range(n + 1)] for i in range(1, n + 1): dp[i][i] = 0
Вычисляем и выводим ответ.
print(f(1, n))