leetcode 813. 最大平均值和的分組
我們将給定的數組 A 分成 K 個相鄰的非空子數組 ,我們的分數由每個子數組内的平均值的總和構成。計算我們所能得到的最大分數是多少。
注意我們必須使用 A 數組中的每一個數進行分組,并且分數不一定需要是整數。
示例:
輸入:
A = [9,1,2,3,9]
K = 3
輸出: 20
解釋:
A 的最優分組是[9], [1, 2, 3], [9]. 得到的分數是 9 + (1 + 2 + 3) / 3 + 9 = 20.
我們也可以把 A 分成[9, 1], [2], [3, 9].
這樣的分組得到的分數為 5 + 2 + 6 = 13, 但不是最大值.
說明:
1 <= A.length <= 100.
1 <= A[i] <= 10000.
1 <= K <= A.length.
答案誤差在 10^-6 内被視為是正确的。
思路
使用動态規劃,
dp[i][k]
表示前
i
個數分成
k
組的最大分數
那麼狀态轉移方程為:
dp[i][k] = max(dp[i][k], dp[j][k - 1] + (s[i] - s[j]) / (i - j))
其中
s[i]
表示前
i
個數的和,也即,目前最大值可以由前面
k-1
組的均值加上目前第
k
組的均值遞推得出
base情況是隻有一組的情況,就依次求解均值即可,
dp[i][1] = s[i] / i
class Solution:
def largestSumOfAverages(self, A: List[int], K: int) -> float:
n = len(A)
dp = [[0] * (K + 1) for _ in range(n + 1)]
s = [0] * (n + 1)
# 基礎情況
for i in range(1, n + 1): # 第一個數對應索引0,注意索引問題
s[i] = s[i - 1] + A[i - 1] # 累加和
dp[i][1] = s[i] / i # 前i個分為一組的均值
for i in range(1, n + 1):
for k in range(2, K + 1):
for j in range(i):
dp[i][k] = max(dp[i][k], dp[j][k - 1] + (s[i] - s[j]) / (i - j))
return dp[-1][-1]