[LeetCode] 1043. Partition Array for Maximum Sum 分隔數組以得到最大和



Given an integer array arr, you should partition the array into (contiguous) subarrays of length at most k. After partitioning, each subarray has their values changed to become the maximum value of that subarray.

Return the largest sum of the given array after partitioning.

Example 1:

Input: arr = [1,15,7,9,2,5,10], k = 3
Output: 84
Explanation: arr becomes [15,15,15,9,10,10,10]

Example 2:

Input: arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4
Output: 83

Example 3:

Input: arr = [1], k = 1
Output: 1

Constraints:

  • 1 <= arr.length <= 500
  • 0 <= arr[i] <= 109
  • 1 <= k <= arr.length

這道題給了一個數組 arr,和一個正整數k,說是將數組分成若干個長度不超過k的子數組,分割后的子數組所有的數字都變成該子數組中的最大值,讓求分割后的所有子數組數字之和。由於分割的子數組長度不固定,用暴力搜索的話將會有很多很多種情況,不出意外的話會超時。對於這種玩子數組,又是求極值的題,刷題老司機們應該立馬就能想到用動態規划 Dynamic Programming 來做。先來定義 dp 數組,先從最簡單的考慮,使用一個一維的 dp 數組,其中 dp[i] 就表示分割數組中的前i個數字組成的數組可以得到的最大的數字之和。下面來考慮狀態轉移方程怎么求,對於 dp[i] 來說,若把最后k個數字分割出來,那么前i個數字就被分成了兩個部分,前 i-k 個數字,其數字之和可以直接由 dp[i-k] 來取得,后面的k個數字,則需要求出其中最大的數字,然后乘以k,用這兩部分之和來更新 dp[i] 即可。由於題目中說了分割的長度不超過k,那么就是說小於k的也是可以的,則需要遍歷 [1, k] 區間所有的長度,均進行分割。接下來看代碼,建立一個大小為 n+1 的 dp 數組,然后i從1遍歷到n,此時新建一個變量 curMax 記錄當前的最大值,然后用j從1遍歷到k,同時要保證 i-j 是大於等於0的,因為需要前半部分存在,實際上這是從第i個數字開始往前找j個數字,然后記錄其中最大的數字 curMax,並且不斷用 dp[i-j] + curMax * j 來更新 dp[i] 即可,參見代碼如下:


class Solution {
public:
    int maxSumAfterPartitioning(vector<int>& arr, int k) {
        int n = arr.size();
        vector<int> dp(n + 1);
        for (int i = 1; i <= n; ++i) {
            int curMax = 0;
            for (int j = 1; j <= k && i - j >= 0; ++j) {
                curMax = max(curMax, arr[i - j]);
                dp[i] = max(dp[i], dp[i - j] + curMax * j);
            }
        }
        return dp[n];
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1043


參考資料:

https://leetcode.com/problems/partition-array-for-maximum-sum/

https://leetcode.com/problems/partition-array-for-maximum-sum/discuss/291057/Java-visualize-the-pattern

https://leetcode.com/problems/partition-array-for-maximum-sum/discuss/290863/JavaC%2B%2BPython-DP-O(K)-Space


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM