最基礎的的最大子段和,設dp[
i]
dp[i]
dp[i
]為以num
[i
]num[i]
num[i]
結尾的最大子段和,有dp[
i]=m
ax(d
p[i−
1]+n
um[i
],nu
m[i]
)dp[i]=max(dp[i-1]+num[i],num[i])
dp[i]=
max(
dp[i
−1]+
num[
i],n
um[i
]),最終結果即為max
(dp[
i]
)max(dp[i])
max(dp
[i])
。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int a[
10001];
tuple<
int,
int,
int>
solve
(int a,
int n)
else
if(maxans(maxans<0)
return
make_tuple
(maxans,ansbeg,ansend);}
intmain()
return0;
}
這個好難= =
題意是將乙個長度為n的序列,分成m段不相交叉的子段,使得他們的和最大,m=1時就是最基礎的最大子段和。
於是可以用dp[
i][j
]dp[i][j]
dp[i][
j]來表示在前j個數中,以num
[j
]num[j]
num[j]
結尾並分為i段的最大和。此時我們可以得出如下遞推式
d p[
i][j
]=ma
xdp[i][j]=max\
dp[i][
j]=m
ax其中
\表示n um
[j
]num[j]
num[j]
單獨分成一段,然後將i
ii到j−1
j-1j−
1分成i−1
i-1i−
1段,dp[
i][j
−1]+
num[
j]
dp[i][j-1]+num[j]
dp[i][
j−1]
+num
[j]則表示將num
[j
]num[j]
num[j]
加入到以num
[j−1
]num[j-1]
num[j−
1]結尾的那一段中。
這題是2023年南京大學計算機系本科生開放日機試第一題,由於限制只有100直接暴力列舉o(n
4)
o(n^4)
o(n4
)即可。
poj1050網上的題解參差不齊,因為只限制100,一堆o(n
4)
o(n^4)
o(n4
)的題解還美其名曰dpdp
dp,o (n
4)
o(n^4)
o(n4
)直接暴力不香嗎,此處百練的鏈結資料限制提高到500,o(n
4)
o(n^4)
o(n4
)會超時,需要o(n
3)
o(n^3)
o(n3)的dpdp
dp思想就是求矩陣行和,化成一維,然後求最大子段和
#include
#include
#include
#include
#include
#include
#include
using namespace std;
//最大子段和
intgetmaxsubsum
(int a,
int n)
return maxans;
}const
int max_len=
501;
int mat[max_len]
[max_len]
;int tem[max_len]
;int
main()
}printf
("%d\n"
,ans);}
return0;
}
最大子段和 (dp
n個整數組成的序列a1,a2,a3,ann,求該序列如ai ai 1 aj的連續子段和的最大值。當所給的整數均為負數時和為0。例如 2,11,4,13,5,2,和最大的子段為 11,4,13。和為20。第1行 整數序列的長度n 2 n 50000 第2 n 1行 n個整數 10 9 ai 10 9 ...
dp 最大子段和
注意 在實際問題中可能題目要求至少選乙個,可能可以乙個都不選 只返回最大子段和 include include using namespace std const int maxn 2e5 10 const int inf 0x7fffffff int n int a maxn int maxsum...
最大子段和 經典dp
n個整數組成的序列a11,a22,a33,ann,求該序列如aii ai 1i 1 ajj的連續子段和的最大值。當所給的整數均為負數時和為0。例如 2,11,4,13,5,2,和最大的子段為 11,4,13。和為20。input 第1行 整數序列的長度n 2 n 50000 第2 n 1行 n個整數...