給一段連續的序列s1, s2, s3, s4 … sx, … sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ sx ≤ 32767).
我們定義了sum(i, j) = si + … + sj (1 ≤ i ≤ j ≤ n).
現在求的是:sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + … + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).也就是m段不相交的連續欄位和的最大值。
sample input
1 3 1 2 3
2 6 -1 4 -2 3 -2 3
sample output68
由於我不會動態規劃,所以我要一點一點的解決問題。。。
(1)首先,這道題為什麼是動態規劃???
按照學長的經驗,這道題讓求的是最大的答案,所以它可能就是道動態規劃的題目。。。。
但是怎麼知道它到底是不是動態規劃呢?
我們通常動態規劃可以將乙個大問題分解為和大問題相同的許多個小的子問題
那麼這道題怎麼分解為各個小的子問題呢?頭疼!!!
答:我突然想起來了,每個數,可以單獨成一段,或者和前面的數並成i段,所以每個答案都可以由dp[j - 1](並成i段)和pre[i - 1](單獨成一段)轉移過來,所以就形成了更小的子問題,再分解就可以了
(2)狀態:我們用dp[ i ][ j ]表示前 j 個數形成i段的和的最大值
狀態轉移方程為:dp[i][j] = max(dp[i - 1][k],dp[i][j - 1]) + a[j];
(i - 1<=k <= j - 1)
(3)壓縮空間:採取的是滾動陣列的做法,就是這道題中的pre陣列
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const
int maxn =
2e5+5;
int dp[maxn]
;int pre[maxn]
;int
main()
memset
(dp,0,
sizeof
(dp));
memset
(pre,0,
sizeof
(pre));
for(
int i =
1;i <= m;i++)}
printf
("%d\n"
,mx)
;//分成m段,取的最大值啊,其實就是mx。
}return0;
}
DP 最大連續子段和
最大連續子段和 hdu 1003 1.問題描述 給定一串整數,例如 6 1 5 4 7,求最大連續子段和?2.演算法介紹 此題不能暴力,o n 2 的時間複雜度必然超時。考慮如下演算法 設mi表示前i個整數包含第i個整數的最大連續子段和。sum i,j 表示第i個整數到第j個整數的和,最大連續子段和...
最大連續子段和
最大連續子段和 給定長度為n的整數序列,a 1.n 求 1,n 某個子區間 i,j 使得a i a j 和最大,或者求出最大的這個和。例如 2,11,4,13,5,2 的最大子段和為20,所求子區間為 2,4 窮舉法 3次for迴圈 第1次for迴圈,遍歷陣列所有數字,即確定子段和的首個數字 第2次...
Problem I 最大連續子段和問題
給定有n個整數 可能為負整數 組成的序列a1,a2,an,求該序列連續的子段和的最大值。如果該序列的所有元素都是負整數時定義其最大子段和為0。例如,當 a1,a2,a3,a4,a5 5,11,4,13,4 2 時,最大子段和為11 4 13 20。第一行整數個數n,第二行為n個整數,每個整數之間用一...