Описание
Есть n
дома на линии. Учитывая массив A
и A[i]
представляет положение i-th
дома. Теперь вам нужно выбрать k
место для создания k
почтовых отделений.
Какое минимальное расстояние сумма от этих n
домов до ближайшего почтового отделения?
Все позиции являются целыми числами.
пример
Пример 1:
Input: A = [1, 2, 3, 4, 5], k = 2
Output: 3
Explanation: Build post offices on position 2 and 4.
Пример 2:
Input: A = [1, 2], k = 1
Output: 1
Explanation: Build post office on position 1 or 2.
Вызов
О ( п ^ 2 ) время
Идеи:
Линейное динамическое программирование (а не диапазон динамического программирования)
Может каждый дом возле почтового отделения, поставить n
дом , разделенный на k
сегменты, и мы должны решить этот k
сегмент длинен. Для того , чтобы помочь нам справиться с подобным положения перед домом.
Установка п [я] [J] представляет J дома до создания оптимального решения, когда почта для этого решения является то, что нам нужно состояния J перед тем, как многие дома разделили я-е почтовое отделение, так что:
f[i][j] = min{f[i - 1][j - x] + sumdis[j - x][j - 1]}
其中 sumdis[l][r] 表示下标范围为 [l, r] 的房子之间建立一个邮局, 这些房子与该邮局的最短距离
(注意f[i][j]中的j表示的第j栋房子从1计数, sumdis从0计数)
sumdis массив может быть реализован из предварительной обработки, а также специфический характер алгоритма, который связан с срединных sumdis [L] [R], которые непосредственно выбрать г -. л + 1 дома промежуточный устанавливают, что почтовое отделение (если даже-донг, необязательно промежуточное соединение двух), то расстояние и дома почтовое отделение является самым коротким.
В качестве граничного дп: F [I] [0] = 0, е [0] [J] = INF, и я> = J F При [I] [J] = 0
Кроме того, такое состояние можно прокручивать определенную оптимизацию массива.
общественный класс Решение { / ** * @param целочисленного массива * @param к целому числу * @return целого * / Int [] [] INIT (INT [] A) { Int N = a.length; INT [] [] дис = новый INT [п + 1] [п + 1]; для (INT I = 1; я <= п; я ++) { для (Int J = I + 1, J <= п; ++ , к) { INT среднего = (I + J) / 2; для (Int к = я; к <= у; ++ , к) дис [I] [J] + = Math.abs (А [к - 1] - А [середина - 1]); } } Вернуть дис; } Общественных INT PostOffice (INT [] A, INT к) { // Записываем код здесь Int N = a.length; Arrays.sort (А); INT [] [] = дис инициализации (А); INT [] [] дп = новый INT [п + 1] [K + 1]; если (п == 0 || к> = a.length) возврат 0; INT анс = Integer.MAX_VALUE; для (INT I = 0; я <= п; ++ я) { дп [I] [1] = дис [1] [I]; } Для (интермедиат пк = 2; пк <= к; пк ++) { для (INT I = пк, я <= п; я ++) { дп [I] [пк] = Integer.MAX_VALUE; для (Int J = 0; J <я; j ++) { если (дп [I] [пк] == Integer.MAX_VALUE || дп [I] [пк]> дп [J] [пк - 1] + [дис + 1] , [I]) J дп [I] [пк] = дп [J] [пк - 1] + дис [J + 1] , [I]; } } } вернуться дп [п] [к]; } }