最大M子段和

2021-09-06 20:18:45 字數 1343 閱讀 6139

最近掉入了dp的深淵,還附加數學知識,爽哉。

在此分析一道提交了17次的dp……

n個整數組成的序列a[1],a[2],a[3],…,a[n],將這n個數劃分為互不相交的m個子段,並且這m個子段的和是最大的。如果m >= n個數中正數的個數,那麼輸出所有正數的和。例如:-2 11 -4 13

-5 6 -2,分為2段,11 -4 13一段,6一段,和為26。

首先根據dp的求什麼設什麼原則,可知這裡的dp陣列表示的就是序列的最大和。為方便我們可以將dp[i][j]表示為前j個數分成i段且包括第j個數的最大和。然後求dp陣列需分為兩種情況:

1.第j個數與第j-1個數共同組成一段,子段數不變,此時,第j-1段也必須是所選段,即dp[i][j]=dp[i][j-1]+a[j];

2.第j段是乙個單獨的子段,則需要在前i-1層中找乙個最大值,再加上a[j],即dp[i][j]=max(dp[i-1][t])+a[j]

(i-1<=t那麼可能的答案就在dp[m][m]至dp[m][n]中。

那麼暴力**就不用多說了

#includeusing namespace std;

int n,m,a[5555],dp[5555][5555],maxx;

int main()

{ cin>>n>>m;

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

cin>>a[i];

for(int i=1;i<=m;i++)

for(int j=i;j<=n;j++)

{ int kk=0;

for(int k=i-1;k然後我們來看看資料範圍

優化其實想起來也不難

我們可以直接將所求的最大值找個地方存起來,這樣就避免了k的這層迴圈可以直接呼叫,**實現的難度在於題目給的空間範圍太小,開三個二維陣列會炸,開兩個一維陣列和乙個二維陣列就不能開成long long,對於後面的點也不可奈何。

因為dp[i][j]只與dp[i-1]有關,本來可以用滾動陣列來優化,但因為我不會所以我們可以想辦法把dp陣列的i階段省略,用f陣列來來存dp[i-1]的值,每做完一層就更新一次f是值,並用乙個maxx來記錄所有的最大值,動態更新,最後輸出就是所求。

真心不容易,在此膜拜dp大佬們。

最大m子段和

最大m子段和問題 給定由n個整數 可能為負 組成的序列a1 a2 a3.an,以及乙個正整數m,要求確定序列的m個不想交子段,使這m個子段的總和最大!設b i,j 表示陣列a的前j項中i個子段和的最大值,並且第i個子段包含a j 1 i m,i j n 則所求的最優值為maxb m,j m j n ...

最大m子段和

51nod 1052 題意描述 給定陣列a,長度為n。給定整數m,求不相交的m段字段和的最大值。當m 1 時 該問題就是最大子段和問題。設dp i 為以a i 結尾的最大子段和,當我們考慮dp i 的時候如果dp i 1 0那麼肯定把a i 接在後面最優,否則,取a i 最優。得到 dp i max...

最大m子段和

最大m子段和 定義一串子段s1,s2,s3 sn 1,sn 求m段不交叉最大子段和 解 設dp i j 代表前j個數分成i段的最大和 包括a j 狀態轉移方程 dp i j max dp i j 1 a j dp i 1 t a j i 1 解釋兩種狀態的最優解 a j 恰好在下一次最優解末項之後,...