Почтовое отделение проблема

Описание

Есть  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];
                } 
            }  
        } 
        вернуться дп [п] [к];
    } 
}

  

рекомендация

отwww.cnblogs.com/FLAGyuri/p/12078315.html