hdu 1024 Max Sum Plus Plus(dp求m个不相交子段和的最大值)
2016-02-15 21:40
399 查看
题意:给定一个数组,求其分成m个不相交子段和最大值的问题。
思路:设Num为给定数组,n为数组中的元素总数,Status[i][j]表示前i个数在选取第i个数的前提下分成j段的最大值(在下面程序中用mmax[]数组表示),其中1<=j<=i<=n && j<=m,状态转移方程为:
Status[i][j]=Max(Status[i-1][j]+Num[i],Max(Status[0][j-1]~Status[i-1][j-1])+Num[i])
乍看一下这个方程挺吓人的,因为题中n的限定范围为1~1,000,000而m得限定范围没有给出,m只要稍微大一点就会爆内存。但仔细分析后就会发现Status[i][j]的求解只和Status[*][j]与Status[*][j-1]有关所以本题只需要两个一维数组即可搞定状态转移。
在进行更进一步的分析还会发现其实Max(Status[0][j-1]~Status[i-1][j-1])根本不需要单独求取。在求取now_Status(保存本次状态的数组)的过程中即可对pre_Status(保存前一次状态的数组)进行同步更新。
思路:设Num为给定数组,n为数组中的元素总数,Status[i][j]表示前i个数在选取第i个数的前提下分成j段的最大值(在下面程序中用mmax[]数组表示),其中1<=j<=i<=n && j<=m,状态转移方程为:
Status[i][j]=Max(Status[i-1][j]+Num[i],Max(Status[0][j-1]~Status[i-1][j-1])+Num[i])
乍看一下这个方程挺吓人的,因为题中n的限定范围为1~1,000,000而m得限定范围没有给出,m只要稍微大一点就会爆内存。但仔细分析后就会发现Status[i][j]的求解只和Status[*][j]与Status[*][j-1]有关所以本题只需要两个一维数组即可搞定状态转移。
在进行更进一步的分析还会发现其实Max(Status[0][j-1]~Status[i-1][j-1])根本不需要单独求取。在求取now_Status(保存本次状态的数组)的过程中即可对pre_Status(保存前一次状态的数组)进行同步更新。
#include<stdio.h> #include<algorithm> #include<iostream> using namespace std; #define MAXN 1000000 #define INF 0x7fffffff int dp[MAXN+10]; int mmax[MAXN+10]; int a[MAXN+10]; int main() { int n,m; int i,j,mmmax; while(scanf("%d%d",&m,&n)!=EOF) { for(i=1; i<=n; i++) { scanf("%d",&a[i]); mmax[i]=0; dp[i]=0; } dp[0]=0; mmax[0]=0; for(i=1; i<=m; i++) { mmmax=-INF; for(j=i; j<=n; j++) { dp[j]=max(dp[j-1]+a[j],mmax[j-1]+a[j]); mmax[j-1]=mmmax; mmmax=max(mmmax,dp[j]); } } printf("%d\n",mmmax); } return 0; }
相关文章推荐
- HTML--表格与表单
- HTML静态网页--框架
- JAVA基础之泛型
- 关于ProgressBar的美化问题
- 关于ProgressBar的美化问题
- 关于ProgressBar的美化问题
- C 构造一个 简单配置文件读取库
- HTML静态网页--图片热点
- 关于ProgressBar的美化问题
- Xcode运行缓慢
- UVA - 12099 The Bookcase 书架
- BIgInteger类和BigDecimal类的理解
- 如何在windows上使用eclipse远程连接hadoop进行程序开发
- poj 3311 Hie with the Pie(Floyd+状压dp)
- null相关函数
- 《MongoDB 权威指南》 学习总结
- HDU 1062
- 数据库慢之Library cache lock
- 【AJAX】——UpdatePanel控件的使用
- 知识越多,越无知