HDU 1024——Max Sum Plus Plus
来源:互联网 发布:卡尔曼滤波跟踪算法 编辑:程序博客网 时间:2024/06/07 00:22
题意:一个数列分成m个子数列,求这m个子数列的最大和。
思路:动态规划。划分子问题:
要分成m个子数列,首先考虑分成m-1个子数列。再增加一个子数列的时候,可以考虑从这m-1个子数列里面找一个最大的,然后加进去一些数字。具体加数字的方案有两种。一种是在m-1个子数列的基础上新增加一个子数列。另一种是若已有了m个子数列,那么新增加的一个数字加到原有的数列中。
dp(i,m)表示分成m个子数列,将第i个数放到末尾的时候最大的和。
当划出m个子数列,将第i个数放到末尾的时候有两种情况。一种是跟i-1个数字放在一个子数列中,这样子数列的个数不会增加。另外一种是从前面i-1个数字依次做结尾,分成m-1个子数列中选一个最大的出来,将第i个数字放进去单独做一个子数列。
动态规划方程
dp(i,m)=max(dp(i-1,m)+ai,maxn(i-1,m-1)+ai)。其中maxn(i-1,m-1)表示dp(1…i-1,m-1)里面最大的一个。
代码如下:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long ll;const int maxn=1000005;const int minn=-2000000000;int a[maxn];int dp[maxn][2];int rec[maxn];int main(){// freopen("data.txt","r",stdin); int m,n; while(scanf("%d%d",&m,&n)!=EOF){ for(int i=1;i<=n;++i){ scanf("%d",&a[i]); } for(int i=0;i<=n;++i){ dp[i][0]=0; dp[i][1]=minn; rec[i]=0; } int tmp=1; for(int j=1;j<=m;++j){ int pre=tmp^1; dp[0][tmp]=minn; for(int i=1;i<=n;++i){ dp[i][tmp]=minn; if(dp[i-1][tmp]>minn){ dp[i][tmp]=dp[i-1][tmp]+a[i]; } dp[i][tmp]=max(dp[i][tmp],rec[i-1]+a[i]); } rec[0]=minn; for(int i=1;i<=n;++i){ rec[i]=minn; if(i>0)rec[i]=max(rec[i],rec[i-1]); rec[i]=max(rec[i],dp[i][tmp]); } tmp=pre; } int ans=minn; for(int i=0;i<=n;++i){ ans=dp[i][tmp^1]>ans?dp[i][tmp^1]:ans; } printf("%d\n",ans); } return 0;}
最开始的时候minn开的不够小,导致错误了。。
这个代码可以优化成以为的。注意到在循环的过程中,pre完全没有用到,用处仅仅是更新tmp。另外,答案也不需要重新扫描一边,rec[n]记录的就是答案。
优化以后的代码:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long ll;const int maxn=1000005;const int minn=-200000000;int a[maxn];int dp[maxn];int rec[maxn];int main(){// freopen("data.txt","r",stdin); int m,n; while(scanf("%d%d",&m,&n)!=EOF){ for(int i=1;i<=n;++i){ scanf("%d",&a[i]); } for(int i=0;i<=n;++i){ dp[i]=0; rec[i]=0; } int tmp=1; for(int j=1;j<=m;++j){ int pre=tmp^1; dp[j-1]=minn; for(int i=j;i<=n;++i){ dp[i]=max(dp[i-1]+a[i],rec[i-1]+a[i]); } rec[j-1]=minn; for(int i=j;i<=n;++i){ rec[i]=minn; rec[i]=max(rec[i],rec[i-1]); rec[i]=max(rec[i],dp[i]); } } printf("%d\n",rec[n]); } return 0;}
0 0
- HDU 1024 — Max Sum Plus Plus
- HDU 1024——Max Sum Plus Plus
- hdu 1024Max Sum Plus Plus
- hdu 1024 Max Sum Plus Plus--DP
- hdu 1024 Max Sum Plus Plus
- hdu 1024 Max Sum Plus Plus
- hdu 1024 Max Sum Plus Plus
- hdu 1024 Max Sum Plus Plus
- hdu 1024 Max Sum Plus Plus
- hdu 1024 Max Sum Plus Plus(dp)
- hdu 1024 max sum plus plus
- HDU 1024 Max Sum Plus Plus
- hdu 1024 Max Sum Plus Plus
- HDU 1024 Max Sum Plus Plus
- 【HDU 1024】 Max Sum Plus Plus
- hdu 1024 Max Sum Plus Plus
- HDU 1024 Max Sum Plus Plus
- hdu-1024-Max Sum Plus Plus-DP
- 第三周项目一(2)
- ios 技术境地
- javascript 获取 <sx:datetimepicker> 的值
- HDU 1104 Remainder
- uva136(优先队列)
- HDU 1024——Max Sum Plus Plus
- php 数组找评委跳水打分习题
- hdu 1166 树状数组 线段树
- Uva 10006 Carmichael Numbers (快速幂)
- 栈,堆,全局,文字常量,代码区总结
- Js 冒泡事件阻止
- 数据结构-线性表的一些基础操作 c++代码
- Java IO流
- poj1222 EXTENDED LIGHTS OUT(YY+高斯消元)