C - Max Sum Plus Plus HDU - 1024
Posted accepting
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C - Max Sum Plus Plus HDU - 1024相关的知识,希望对你有一定的参考价值。
用二位数组dp[i][j]记录组数为i,前j个数字的最大子段和。
转移方程:
dp[i][j],考虑第j个数,第j个数可以并到前面那一组,此时dp[i][j]=dp[i][j-1]+arr[j],第j个数也可以是作为新的一组,那么dp[i][j]=max(dp[i-1][k])(i-1<=k<=j-1)+arr[j]。我们只要求出前i-1组最大的字段和,然后加上arr[j]这一新的组就行了。
二维数组(o(n^3))的写法
for(int i=1;i<=m;i++) for(int j=i;j<=n;j++){ int tmp=-INF; for(int k=i-1;k<=j-1;k++){ tmp=max(tmp,dp[i-1][k]); } dp[i][j]=max(dp[i][j-1],tmp)+arr[j]; }
优化:
注意我们把数组写成2维的目的就是在求第i组时,要用到第i-1组的值,o(n^3)写法中,最后一个for的目的就是求i-1的组数下,前k个数的最大值。所以我们可以用一个数组在dp[i][j]处理出来之后,记录dp[i][j]。当我
再次用到dp[i-1][j]时,可以直接调用了。因此dp[i][j]=max(dp[i][j-1],ma[j-1])+arr[j]。再优化:dp[j]=max(dp[j-1],ma[j-1])+arr[j]。
for(ll i=1;i<=m;i++){//第i组 tmp=-INF; for(ll j=i;j<=n;j++){//考虑第j个人 dp[j]=max(dp[j-1],ma[j-1])+arr[j]; ma[j-1]=tmp; tmp=max(tmp,dp[j]); } }
注意:不可以颠倒ma[j-1]=tmp和dp[j]的位置,因为ma[j-1]记录的是i-1时的值。
以上是关于C - Max Sum Plus Plus HDU - 1024的主要内容,如果未能解决你的问题,请参考以下文章
HDU 2746 ——Max Sum Plus Plus Plus
hdu1024 Max Sum Plus Plus (Dp)