Convex hull trick — различия между версиями
(Содержимое страницы заменено на «==первый заголовок== текст текст ==второй== текст текст») |
|||
Строка 1: | Строка 1: | ||
− | == | + | ==Постановка примера задачи== |
− | + | Есть n деревьев с высотами a1, a2, … an. Требуется спилить их все, потратив минимальное количество монет на заправку бензопилы. Но пила устроена так, что после уменьшения высоты спиливаемого дерева на 1 ее надо заправить. Причем стоимость заправки зависит от срубленных (полностью) деревьев. Если сейчас максимальный индекс срубленного дерева равен i, то цена заправки равна ci. Изначально пила заправлена. | |
− | + | И известны следующие ограничения : c[n] = 0, a[1] = 1, a[i] возрастают, c[i] убывают. | |
− | == | + | (Задача с codeforces.com) |
− | + | ==Наивное решение== | |
+ | Понятно, что нужно затратив минимальную стоимость срубить последнее (n-е) дерево, т.к. после него все деревья можно будет пилить бесплатно (т.к. c[n] = 0). Посчитаем следующую динамику : dp[i] - минимальная стоимость, заплатив которую будет срублено дерево номер i. Тогда dp[i] = min(dp[j] + a[i] * c[j]) по всем j < i. То есть понятно, что выгодно рубить сначала более дорогие и низкие деревья, а потом более высокие и дешвые (док-во этого факта оставляется читателям как несложное упражнение). Тогда переберем j < i - индекс предыдущего срубленного дерева. Пусть мы его срубили отптимальным (в смысле денег) способом. Тогда просто a[i] раз уменьшим высоту дерева i на 1. Каждый такой раз будем платить c[j] за последующую заправку пилы. Итак, на сруб i-го дерева мы заплатили a[i]*c[j].
Нетрудно видеть, что такая динамика работает за O(n^2). |
Версия 18:59, 23 ноября 2016
Постановка примера задачи
Есть n деревьев с высотами a1, a2, … an. Требуется спилить их все, потратив минимальное количество монет на заправку бензопилы. Но пила устроена так, что после уменьшения высоты спиливаемого дерева на 1 ее надо заправить. Причем стоимость заправки зависит от срубленных (полностью) деревьев. Если сейчас максимальный индекс срубленного дерева равен i, то цена заправки равна ci. Изначально пила заправлена. И известны следующие ограничения : c[n] = 0, a[1] = 1, a[i] возрастают, c[i] убывают. (Задача с codeforces.com)
Наивное решение
Понятно, что нужно затратив минимальную стоимость срубить последнее (n-е) дерево, т.к. после него все деревья можно будет пилить бесплатно (т.к. c[n] = 0). Посчитаем следующую динамику : dp[i] - минимальная стоимость, заплатив которую будет срублено дерево номер i. Тогда dp[i] = min(dp[j] + a[i] * c[j]) по всем j < i. То есть понятно, что выгодно рубить сначала более дорогие и низкие деревья, а потом более высокие и дешвые (док-во этого факта оставляется читателям как несложное упражнение). Тогда переберем j < i - индекс предыдущего срубленного дерева. Пусть мы его срубили отптимальным (в смысле денег) способом. Тогда просто a[i] раз уменьшим высоту дерева i на 1. Каждый такой раз будем платить c[j] за последующую заправку пилы. Итак, на сруб i-го дерева мы заплатили a[i]*c[j]. Нетрудно видеть, что такая динамика работает за O(n^2).