【區間 dp】B021_LC_分隔數組以得到最大和(預處理區間最大值 / 優化)

一、Problem

給出整數數組 A,將該數組分隔爲長度最多爲 K 的幾個(連續)子數組。分隔完成後,每個子數組的中的值都會變爲該子數組中的最大值。

返回給定數組完成分隔後的最大和。

輸入:A = [1,15,7,9,2,5,10], K = 3
輸出:84
解釋:A 變爲 [15,15,15,9,10,10,10]

提示:

1 <= K <= A.length <= 500
0 <= A[i] <= 10^6

二、Solution

方法一:預處理區間最大值

這題我一看兩個條件,就連想到的二維 dp,即 f[i][j]f[i][j] 表示將前 ii 個元素分成長度爲 jji/j 個子數組時的最大和,最後返回 f[n][K]f[n][K],但這可以優化成一維,爲什麼?因爲我們並不關心它具體分成幾個子數組,最終都會轉移到 f[i][j] 上

  • 定義狀態
    • f[i]f[i] 序列 A[0:i]A[0:i] 的分成最多 k 個子數組的最大和
  • 思考初始化:
    • f[0...n1]=0f[0...n-1] = 0
  • 思考狀態轉移方程
    • f[i]=max(f[i], f[ij]+max[ij][i1]×j)f[i] = max(f[i],\ f[i-j] + max[i-j][i-1] × j) 子數組 A[0:i]A[0:i] 的最大和由兩部分組成,一是子數組 A[0:ij]A[0:i-j] 的最大和,二是 A[ij:i]A[i-j:i] 的最大得分組成;而第二部分是未知的,所以第二部分只能通過枚舉且取其中的最大和
  • 思考輸出f[n]f[n]
class Solution {
    public int maxSumAfterPartitioning(int[] A, int K) {
    	int n = A.length, f[] = new int[n+1], g[][] = new int[n][n];
    	for (int i = 0; i < n; i++) {
    		g[i][i] = A[i];
    		for (int j = i+1; j < n; j++)
    			g[i][j] = Math.max(g[i][j-1], A[j]);
    	}

        for (int i = 1; i <= n; i++)
        for (int j = 1; j <= i && j <= K; j++) {
        	f[i] = Math.max(f[i], f[i-j] + g[i-j][i-1] * j);
        }
    	return f[n];
    }
}

複雜度分析

  • 時間複雜度:O(n2)O(n^2)
  • 空間複雜度:O(n2)O(n^2)

方法二:優化

代辦…


複雜度分析

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