动态规划训练14 [Max Sum Plus Plus HDU - 1024 ]
生活随笔
收集整理的這篇文章主要介紹了
动态规划训练14 [Max Sum Plus Plus HDU - 1024 ]
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Max Sum Plus Plus
? HDU - 1024?
題意大致是說(shuō)給你你個(gè)序列,把它劃分成不相交的幾個(gè)連續(xù)的部分,然后把這個(gè)幾個(gè)部分求和,求出和的最大值。
我們定義子結(jié)構(gòu) ?dp[i][j] ?表示的是從前j個(gè)元素,劃分成i段所得的最大和。
則我們可以得到轉(zhuǎn)移方程。
考慮最后一個(gè)元素
(1)當(dāng)最后一個(gè)元素自成一組
dp[i][j] 由 max{ dp[i-1][k] + a[i] } 轉(zhuǎn)移而來(lái)
(2)當(dāng)最后一個(gè)元素與前一個(gè)元素連起來(lái)成一組
dp[i][j] 由 dp[i][j-1] + a[i]轉(zhuǎn)移而來(lái)
但這樣的話(huà),空間復(fù)雜度為O(n2),顯然是不夠的,因此要用滾動(dòng)數(shù)組來(lái)優(yōu)化
時(shí)間復(fù)雜度為O(n3)也是不夠的,也需要優(yōu)化,其實(shí)轉(zhuǎn)移方程(1)里的最大值可以用一個(gè)數(shù)組維護(hù)起來(lái)
#include <cstdio.> #include <cstring> #include <algorithm> using namespace std; int a[1000000]; int sum[1000000]; int dp[2][1000000]; int mx[2][1000000]; main(){int m,n;while(scanf("%d%d",&m,&n) != EOF){memset(dp,0,sizeof(dp));for(int i = 0;i < n;i++){mx[0][i] = 0;mx[1][i] = -1e9;}for(int i = 0;i < n;i++){scanf("%d",&a[i]);sum[i] = i != 0 ? a[i] + sum[i-1]:a[i];}for(int i = 1;i <= m;i++){mx[i&1][i-1] = -1e9;dp[i&1][i-1] = sum[i-1];mx[i&1][i-1] = max(mx[i&1][i-1],dp[i&1][i-1]);for(int j = i;j < n;j++){dp[i&1][j] = max(dp[i&1][j-1] + a[j],mx[(i-1)&1][j-1] + a[j]);mx[i&1][j] = max(mx[i&1][j-1],dp[(i&1)][j]);}}int ans = -1e9;for(int i = m-1;i < n;i++){ans = max(ans,dp[m&1][i]);}printf("%d\n",ans); } }總結(jié)
以上是生活随笔為你收集整理的动态规划训练14 [Max Sum Plus Plus HDU - 1024 ]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 二郎神的狗叫什么 哮天犬简介
- 下一篇: 动态规划训练15 [Monkey and