EduBrick
← вернуться к уроку · Продвинутый уровень: проверь себя

L. Распил брусьев

2000 мс · 256 МБ · всё или ничего

Брус длиной LL надо распилить в заданных местах. Распил бруска длиной kk стоит kk рублей независимо от того, где именно пилят. Найдите наименьшую суммарную стоимость.

Пример из условия: брус длиной 10, распилы на 2, 4 и 7. Если пилить по порядку 2, 4, 7 - это 10+8+6=2410 + 8 + 6 = 24. Если сначала на 4, потом 2, потом 7 - 10+4+6=2010 + 4 + 6 = 20.

Состояние

Добавим к списку распилов концы бруса: c0=0c_0 = 0 и cN+1=Lc_{N+1} = L. Тогда любой кусок в процессе работы - это отрезок между двумя точками из этого списка.

dp[i][j]dp[i][j] - стоимость распила куска от cic_i до cjc_j по всем внутренним точкам. Перебираем, какой распил делается первым:

dp[i][j]=(cjci)+mini<k<j(dp[i][k]+dp[k][j])dp[i][j] = (c_j - c_i) + \min_{i < k < j} \bigl( dp[i][k] + dp[k][j] \bigr)

Слагаемое cjcic_j - c_i - это цена первого распила: он всегда делается по целому куску, какой бы точки ни касался. База: dp[i][i+1]=0dp[i][i+1] = 0, внутри резать нечего.

Это ровно та же схема, что в задаче про склейку куч, только «снаружи внутрь», а не «изнутри наружу». Полезно заметить, что min\min и слагаемое поменялись местами по сравнению с умножением матриц: там цена зависела от точки разреза, тут - нет.

O(N3)O(N^3) при N100N \le 100 - миллион операций.

Про жадность

Соблазн пилить всегда посередине силён, и на примере из условия он даже срабатывает. Но это не общее правило: постройте набор из двух распилов, на котором «посередине» проигрывает, - это полезнее, чем прочитать про это здесь.

Подробнее: «Динамика по подотрезкам».

Формат ввода

В первой строке - числа LL и NN (2L1062 \le L \le 10^6, 1N1001 \le N \le 100) - длина бруса и количество распилов.

Во второй строке - NN чисел CiC_i (0<Ci<L0 < C_i < L) в строго возрастающем порядке.

Формат вывода

Одно число - наименьшая стоимость распила.

Примеры

ввод
10 3
2 4 7
вывод
20
ввод
2 1
1
вывод
2
Войдите, чтобы отправлять решения.
← Вернуться к уроку