码迷,mamicode.com
首页 > 其他好文 > 详细

HDU ACM 1024 Max Sum Plus Plus ->最大连续子序列和的增强版

时间:2015-06-06 18:18:43      阅读:330      评论:0      收藏:0      [点我收藏+]

标签:c   c++   acm   算法   编程   

#include<iostream>
#include<limits.h>
using namespace std;

#define N 1000005
int a[N],dp[N],maxpre[N];

int max(int a,int b)
{
	return a>b?a:b;
}

int main()
{
	int i,j,n,m,tmp;

	while(scanf("%d%d",&m,&n)==2)
	{
		for(i=1;i<=n;i++)
			scanf("%d",&a[i]);
		memset(dp,0,sizeof(dp));
		memset(maxpre,0,sizeof(maxpre));
		for(i=1;i<=m;i++)     //m个段
		{
			tmp=INT_MIN;
			for(j=i;j<=n;j++)
			{
				dp[j]=max(dp[j-1],maxpre[j-1])+a[j];
				maxpre[j-1]=tmp;
				tmp=max(tmp,dp[j]);
			}
		}
		printf("%d\n",tmp);
	}
    return 0;
}

参考自:http://www.cnblogs.com/jiangjing/archive/2013/07/25/3214729.html

题意:最大和连续子序列的增强版,要求从一序列中取出若干段,这些段之间不能交叉,使得和最大并输出。
分析:用dp[i][j]表示前j个数取出i段得到的最大值,那么状态转移方程为dp[i][j]=max(dp[i][j-1]+a[j],dp[i-1][k]+a[j])  i-1<=k<=j-1
这个状态转移方程表达了两种不同的选择:第一个就是第j个连在第j-1个所在的段的后面,第二个就是第j个为新的一段的第一个数字。
由于数字的个数比较大,而题目中给定的m未知,怕超内存,所以要想办法开设一维数组来代替,后来发现可以用dp[j]表示表示到第j个的时候
最大和。解决了空间的问题了,现在就是时间的问题了,dp[i-1][k]  i-1<=k<=j-1,如果这里用for循环去写的话,由于题目中给定的数字个数
太大,那肯定会超时的!所以我们可以开设一个数组来记录上一状态的j-1个前的最大值,具体看代码实现吧!!

HDU ACM 1024 Max Sum Plus Plus ->最大连续子序列和的增强版

标签:c   c++   acm   算法   编程   

原文地址:http://blog.csdn.net/a809146548/article/details/46389385

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!