k個最大的m段子陣列和

2021-07-05 06:26:46 字數 2052 閱讀 4723

給定長度為n的陣列a,從中選擇k個長度為m的子陣列,要求和最大。

形式描述為:選擇

k 個子陣列[l1

, r1

], [l2

, r2

], ..., [lk

l1, rk

](1 ≤ l1

≤r1 ≤l

2 ≤ r

2

≤... ≤lk

≤ rk

≤ n; ri

−ri+

1

), 使得∑k

i=1∑

rij=

lipj

【思路1】先從簡單粗暴的方法入手,怎麼辦?尋找所有的k個長度為m的子陣列,然後選擇其中和最小的。第乙個長度為m的子陣列開始位置可能為0...(k-1)*m,然後第二個子陣列的下標?第三個子陣列下標?太複雜了而且時間複雜度肯定超高,不能忍,換個方法吧。

【思路2】再看一下問題,要求和最大,求最值問題十有**都是dp問題,試試吧。dp題目子問題怎麼定義是關鍵,然後這東西基本只能靠經驗了(嗯,演算法導論上就是這麼說的)。從後往前考慮,那麼對於最後乙個元素,只有兩種情況,被選中到子陣列中或者沒有被選到子陣列中。如果被選中,那麼首先計算最後m個元素的和,剩下的問題就化為從前面長度為n-m的陣列中選擇k-1組和最大的子陣列。如果沒選中最後乙個,也好辦,直接轉化為從前面n-1個元素中選擇k組和最大的子陣列。分析後我們有:

子問題定義:   dp[i][j] = 從前i個元素中選擇j個子陣列的最大和

狀態轉移方程:  dp[i][j] = max(dp[i-1][j], dp[i-m][j-1] + sum(a[i-m]...a[i-1]))

初始條件:        dp[0][j] = 0; dp[i][0] = 0; if (i < j * m) dp[i][j] = 0;

1 #include 2 #include 

3 #include 4 #include 5 #include 6 #include 7

using

namespace

std;89

intmain()

1019

20//

dp[i][j] = choose j pairs integers from the first i elements

21//

then base on the ith is chosen or not, there are two case:

22//

not choose ith element, the dp[i][j] = dp[i-1][j]

23//

choose ith element, the dp[i][j] = dp[i-m][j-1] + sum(a[i-1]...a[i-m])

24//

so dp[i][j] = max(dp[i-1][j], dp[i-m][j-1] + sum(a[i-1]...a[i-m])

25//

base case: assert (i >= j * m) if not 0 dp[i][j] = 0

26//

the problem is equal to find dp[n][k]

2728 vectorlong

long> > dp(n+1, vector

long>(k+1, 0

));29

30//

base case

31for (int i = 0; i < n + 1; ++i)

3239}40

}4142//

bottom to up

43for (int i = 1; i < n + 1; ++i)

445253}

54}5556

long

long ans =dp[n][k];

57 cout << ans <

58return0;

59 }

書上講解 最大m段子段和問題

描述 題解 設f i j 表示前i個數字分成了j段的最大子段和。則f i j max f i 1 j a i 第i個數字和第j段合在一起 f k j 1 a i 第i個數字作為第j段的第乙個數字,同時在j 1段的情況中找到和最大的那個 這樣的時間複雜度是 o m n 2 的,的寫法在 1中 接下來我...

陣列的第k個最大元素

提交 總結在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。示例 1 輸入 3,2,1,5,6,4 和 k 2 輸出 5 示例 2 輸入 3,2,3,1,2,4,5,5,6 和 k 4 輸出 4 說明 你可以假設 k 總是有效...

陣列中的第k個最大元素

在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。示例 1 輸入 3,2,1,5,6,4 和 k 2 輸出 5 示例 2 輸入 3,2,3,1,2,4,5,5,6 和 k 4 輸出 4 說明 你可以假設 k 總是有效的,且 1...