Example #1
0
 /**
  * @param A an integer array
  * @param k an integer
  * @return an integer
  */
 int postOffice(vector<int>& A, int k) {
     // Write your code here
     // Naive DP method.
     // If dp[i][j] represents i post office between 0 - j houses included.
     // dp[i][j] = min_m(dp[i - 1][m] + w[m+1][j]), i-1<= m <=j-1
     int n = A.size();
     
     // Always remember to check the second variable.
     if (A.empty() || k >= n)
         return 0;
     
     // Necessary to make dp straightforward.
     sort(A.begin(), A.end());
     
     // cost array stores w[i][j] which represents the minimum cost
     // to build a post office between A[i] and A[j] included. 
     vector<vector<int>> cost(n, vector<int>(n, 0));
     computeMinCost(A, cost);
     
     // Here res[0][j] is actually not used at all for conveniency.
     vector<vector<int>> res(k + 1, vector<int>(n, INT_MAX));
     // starting from one post office.
     for (int i = 1; i <= k; i++) {
         for (int j = 0; j < n; j++) {
             if (i == 1) {
                 res[i][j] = cost[0][j];
             } else {
                 for (int m = i - 1; m <= j - 1; m++)
                     res[i][j] = min(res[i][j], res[i-1][m] + cost[m + 1][j]);
             }
         }
     }
     return res[k][n - 1];
 }
Example #2
0
 /**
  * @param A an integer array
  * @param k an integer
  * @return an integer
  */
 int postOffice(vector<int>& A, int k) {
     // Write your code here
     int n = A.size();
     
     // Always remember to check the second variable.
     if (A.empty() || k >= n)
         return 0;
     
     // Necessary to make dp straightforward.
     sort(A.begin(), A.end());
     
     // cost array stores w[i][j] which represents the minimum cost
     // to build a post office between A[i] and A[j] included. 
     vector<vector<int>> cost(n, vector<int>(n, 0));
     computeMinCost(A, cost);
     
     // res[i][j] represents the minimum distance sum of building i post offices
     // between 0 and j houses.
     vector<vector<int>> res(k + 1, vector<int>(n, INT_MAX));
     
     // s[i][j] represents the number of villages covered by
     // previous i-1 post offfice, in the optimum of res[i][j].
     // s[1][j] == 0 since there is only one post office, the previous 
     // covers nothing, we set it to 0, as the starting point of dp.
     vector<vector<int>> s(n + 1, vector<int>(n, 0));
     
     for (int i = 0; i < n; i++)
         res[1][i] = cost[0][i];
     
     // starting from one post office
     for (int i = 2; i <= k; i++) {
         // Set j to n - 1 first.
         // we can get the s[i][n - 1] and res[i][n-1] in the first DP.
         for (int m = s[i - 1][n - 1]; m <= n - 2; m++) {
             int temp = res[i - 1][m] + cost[m + 1][n - 1];
             if (temp < res[i][n - 1]) {
                 res[i][n - 1] = temp;
                 s[i][n - 1] = m;
             }
         }
         
         // We used s[i][j+1] in the following loop to set the upper bound.
         // Which used the monoticity property of the problem.
         for (int j = n - 2; j >= i; j--) {
             for (int m = s[i - 1][j]; m <= s[i][j + 1]; m++) {
                 int temp = res[i - 1][m] + cost[m + 1][j];
                 if (temp < res[i][j]) {
                     res[i][j] = temp;
                     s[i][j] = m;
                 }
             }
         }
     }
     
     return res[k][n - 1];
 }
Example #3
0
    /**
     * @param A an integer array
     * @param k an integer
     * @return an integer
     */
    int postOffice(vector<int>& A, int k) {
        const int n = A.size();
        if (A.empty() || k >= n) {
            return 0;
        }

        sort(A.begin(), A.end());  // Time:  O(nlogn)

        // Precompute cost.
        // Time:  O(n^3)
        // Space: O(n^2)
        vector<vector<int>> cost(A.size() + 1, vector<int>(A.size() + 1, 0));
        computeMinCost(A, cost);

        // DP of sum.
        // Time:  O(k * n^2)
        // Space: O(k * n)
        // sum[i][j] denotes the smallest sum of
        // picking i post offices for the first j houses.
        // sum[i][j+r] = min(sum[i-1][j]+cost[j+1][j+r]) for every r
        // 
        vector<vector<int>> sum(k + 1, vector<int>(A.size() + 1, INT_MAX));
        
        sum[0][0]=0;
        for (int i = 1; i <= k; ++i) {
            for (int j = 0; j < n; ++j) {
                if (sum[i - 1][j] != INT_MAX) {
                    for (int r = 1; j + r <= n; ++r) {
                       sum[i][j + r] = min(sum[i][j + r],
                                           sum[i - 1][j] + cost[j + 1][j + r]);
                    }
                }
            }
        }
        return sum[k][n];
    }