【區間 dp】A014_LC_安排郵筒(麻煩的邊界)

一、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

  • 定義狀態
    • f[i][j]f[i][j] 表示前 ii 個房子放 jj 個郵箱的最小距離
    • d[i][j]d[i][j] 表示從房子 ii 個到房子 jj 放一個郵箱的得到的最小距離
  • 思考初始化:
    • f[i][1]=d[0][i]f[i][1] = d[0][i]
  • 思考狀態轉移方程
    • f[i][j]=min(f[i][j],f[k1][j1]+d[k][i]f[i][j] = min(f[i][j], f[k-1][j-1] + d[k][i] 表示前面 k1k-1 個房間用 j1j-1 個郵箱照顧,然後區間 [k,i][k, i] 這些房間用一個郵箱照顧的最短距離。
  • 思考輸出f[n1][K]f[n-1][K]
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 號房間的安排一個郵箱已經有答案了,所以選擇枚舉的是安排 jj 個郵箱的最小距離。

Q3:k 爲什麼從 j-1 開始?
A3:這裏考慮的是極限問題:k 枚舉的是最後一個郵箱的覆蓋範圍的起點,那 k 什麼時候覆蓋最多呢?答案是前 j1j-1 個郵箱各自負責一個房間的時候,最後一個郵箱會覆蓋最多房間。

複雜度分析

  • 時間複雜度:O(n×k)O(n × k )
  • 空間複雜度:O(n×k)O(n × k)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章