一、Problem
Given the array houses and an integer k. where houses[i] is the location of the ith house along a street, your task is to allocate k mailboxes in the street.
Return the minimum total distance between each house and its nearest mailbox.
The answer is guaranteed to fit in a 32-bit signed integer.
Input: houses = [1,4,8,10,20], k = 3
Output: 5
Explanation: Allocate mailboxes in position 3, 9 and 20.
Minimum total distance from each houses to nearest mailboxes is |3-1| + |4-3| + |9-8| + |10-9| + |20-20| = 5
二、Solution
方法一:dp
- 定義狀態:
- 表示前 個房子放 個郵箱的最小距離
- 表示從房子 個到房子 放一個郵箱的得到的最小距離
- 思考初始化:
- 思考狀態轉移方程:
- 表示前面 個房間用 個郵箱照顧,然後區間 這些房間用一個郵箱照顧的最短距離。
- 思考輸出:
class Solution {
public int minDistance(int[] h, int K) {
Arrays.sort(h);
int n = h.length, INF = 0x3f3f3f3f, f[][] = new int[n][K+1], d[][] = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = i; j < n; j++) {
int mid = i + j >>> 1;
for (int k = i; k <= j; k++)
d[i][j] += Math.abs(h[k] - h[mid]);
}
for (int i = 0; i < n; i++)
for (int j = 1; j <= K; j++)
f[i][j] = INF;
for (int i = 0; i < n; i++) f[i][1] = d[0][i];
for (int i = 1; i < n; i++)
for (int j = 2; j <= K && j <= i+1; j++) //j是個數,但i是下標
for (int k = j-1; k <= i; k++) {
f[i][j] = Math.min(f[i][j], f[k-1][j-1] + d[k][i]);
}
return f[n-1][K];
}
}
Q1:爲什麼 j <= K && j <= i+1
A1:因爲假如有 i+1 個房屋,那麼對這 i+1 個房屋安排多少個郵箱合適呢(ps:k <= n),基於這個條件,在兩個房間中間位置放置一個郵箱是最優的。
Q2:j 爲什麼從 2 開始?
A2:因爲 0~i 號房間的安排一個郵箱已經有答案了,所以選擇枚舉的是安排 個郵箱的最小距離。
Q3:k 爲什麼從 j-1 開始?
A3:這裏考慮的是極限問題:k 枚舉的是最後一個郵箱的覆蓋範圍的起點,那 k 什麼時候覆蓋最多呢?答案是前 個郵箱各自負責一個房間的時候,最後一個郵箱會覆蓋最多房間。
複雜度分析
- 時間複雜度:,
- 空間複雜度:,