`
人生难得糊涂
  • 浏览: 117380 次
社区版块
存档分类
最新评论

POJ2479——动态规划求最大子段

 
阅读更多

题目大意:

求一共序列的两个字段最大和。

例如

1 -1 2 2 3 -3 4 -4 5 -5
In the sample, we choose {2,2,3,-3,4} and {5}, then we can get the answer.
答案是 13

 

 

分析:

在做这道题之前,我们先看看求一序列的最大子段是怎样求的。

设a[i]为序列的第i个元素。设b[j]为i到j的子段和的最大值(i从0变化到j),那么当b[j-1]>0时,b[j]=b[i-1]+a[j],

否则 b[j]=a[i];那么b数组中的最大值既所求子段。那么我们可以写下如下程序

 

#include<iostream>
using namespace std;
int main()
{
	int a[100];
	int n;
	int b;
	int i;
	int sum;
	cin>>n;
	for(i=0;i<n;i++)
		cin>>a[i];
	b=a[0];
	sum=a[0];
	for(i=1;i<n;i++)
	{
		if(b>0)
			b=b+a[i];
		else
			b=a[i];
		if(sum<b)
			sum=b;
	}
	cout<<sum<<endl;
	return 0;

}

 

 

 好的,现在我们通过上面的程序已经会求一个序列的最大子段了,我们在回过来看这道题哦,它是要求两个子段的和最大,那么我们该怎么从求序列的最大子段,求两个子段的最大和呢?我们假设所求两个子序列最大和为sum,两个子序列分别为left和right,这两个子段一个在序列的左边,一个在右边。那么在它们中间必定有一个分割点(这个点即可能被包含在其中一个子段中,也可能不。)设这个点为k,那么left必定是从0到k这个子段的最大子序列(用反证法证明,假设存在在0到k这个范围内的一个子序列nleft的比left大,那么nleft+right将大于sum,这就与上面假设最和为sum矛盾,所以必定不成立比left大的nleft),right必定是从k+1到n-1(n为序列长度)这个子段的最大子序列(证明过程同上),那么我们现在的问题就转换成了求两个最大子序列。我们从左边开始,往右边求出每个点的最大左子段和,保存在b[]数组中,然后再从右边开始,往左边求出每个点的最大右子段和,然后再遍历每个点,求出每个点的两个最大左右子段和,即可得出答案。

代码如下。

#include<iostream>
using namespace std;
#define len 50010
int main()
{
	int a[len];
	int b[len];
	int c[len];
	int num;
	int i;
	int n;
	scanf("%d",&num);
	while(num--)
	{
		scanf("%d",&n);//注意这道题用cin输入会超时
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
//以下代码为从左往右,求出每个点的右边最大子段
		b[0]=a[0];
		for(i=1;i<n;i++)
		{
			if(b[i-1]>0)
				b[i]=b[i-1]+a[i];
			else
				b[i]=a[i];
		}
		for(i=1;i<n;i++)
		{
			if(b[i]<b[i-1])
				b[i]=b[i-1];
		}
//以下代码为从右往左,求出每个点的左边最大子段
		c[n-1]=a[n-1];
		for(i=n-2;i>=0;i--)
		{
			if(c[i+1]>0)
				c[i]=c[i+1]+a[i];
			else
				c[i]=a[i];
		}
		for(i=n-2;i>=0;i--)
		{
			if(c[i]<c[i+1])
				c[i]=c[i+1];
		}
//遍历每个点的子段和,求出最大的那个
		int s=b[0]+c[1];
		for(i=0;i<n-1;i++)
		{
			if(b[i]+c[i+1]>s)
				s=b[i]+c[i+1];
		}
		printf("%d\n",s);
	}
	return 0;
}

 

0
0
分享到:
评论

相关推荐

    poj2488——dfs深度优先遍历

    poj 2488——dfs深度优先遍历 //给行数列数,求问能否遍历,给出字典序的一种遍历

    北大POJ初级-动态规划

    北京大学的在线编程竞赛平台POJ(Problem Online Judge)为初学者提供了一系列的编程题目,其中“北大POJ初级-动态规划”是专门为学习和训练这个主题设立的板块。在这个部分,学员可以通过解题报告和已通过验证(AC...

    强大的POJ分类——各类编程简单题及其算法分类

    【强大的POJ分类——各类编程简单题及其算法分类】 POJ,全称为Peking University Online Judge,是北京大学提供的一个在线编程题目平台,支持多种编程语言,包括Pascal、C、C++、Java、Fortran、Python等。这个...

    poj2479 Maximum sum

    poj2479代码 Maximum sum 对于这道题,我的思路是先从左到右,计算并存储每个节点

    poj1260 —— 最少的钱买完所需珍珠

    c表示有多少种珍珠 ai 表示第i种珍珠所需的数量 pi 表示第i种珍珠的价钱 每买一种珍珠都需要付额外的10 * pi的钱,便宜的珍珠可以用贵的珍珠来代替,求最少的钱的总数。

    POJ 1015 动态规划

    POJ上的一道题目,自己写的代码,因为想下载别人的, 所以就放上了。

    poj经典动态规划题目解题报告

    poj经典动态规划题目解题报告,包括经典的动态规划题目20多道,可以作为学习动态规划系统的资料,包括题目: Pku acm 1179 Polygon Pku acm 1125 Stockbroker Grapevine Pku acm 1160 post office Pku ...

    poj dp总结,动态规划分类

    ### poj dp总结:动态规划分类 #### 概述 动态规划(Dynamic Programming,简称DP)是一种在计算机科学和数学中广泛使用的算法策略,用于解决最优化问题。它通过将复杂问题分解为较简单的子问题来求解,并利用这些...

    POJ动态规划题目全面总结

    PKU Online Judge上面很全面的动态规划试题总结。动态规划是ACM考点中最重要的一大类算法之一,对于工作人员来说,动态规划也是实际开发中经常会遇到的算法。这是POJ上面很多DP题目的总结与深刻分析。利于算法学习,...

    POJ 1006 源代码——中国剩余定理分析

    POJ 1006 源代码——中国剩余定理分析POJ 1006 源代码——中国剩余定理分析POJ 1006 源代码——中国剩余定理分析

    ACM课程论文——详解动态规划

    在ZOJ和POJ这样的在线判题平台上,有很多动态规划的题目供参赛者练习,通过解决这些题目,可以深入理解和掌握动态规划的运用。 动态规划的适用范围广泛,不仅仅局限于时间相关的动态过程,还可以应用于与时间无关的...

    动态规划算法poj1088滑雪实验报告

    标题中的“动态规划算法poj1088滑雪实验报告”指的是使用动态规划算法解决北京大学ICPC在线测评系统POJ中编号为1088的滑雪问题。这个问题旨在通过一个直观的应用实例,帮助学习者深入理解动态规划的概念,并熟练运用...

    POJ1015-Jury Compromise【动态规划DP】

    【标题】"POJ1015-Jury Compromise" 是一个编程竞赛题目,主要涉及的是动态规划(Dynamic Programming, 简称DP)的算法应用。动态规划是一种解决复杂问题的有效方法,它通过将问题分解成子问题,并存储子问题的解来...

    POj 1001源代码——高精度乘单精度

    POj 1001源代码——高精度乘单精度POj 1001源代码——高精度乘单精度POj 1001源代码——高精度乘单精度POj 1001源代码——高精度乘单精度

    POJ2485Highways——JAVA版

    ### POJ2485Highways —— JAVA版 #### 题目背景与目标 在虚拟的岛国Flatopia中,尽管地形平坦,但该国却没有一条公共高速公路,这导致了交通上的不便。为了解决这个问题,Flatopia政府计划修建一些高速公路,使得...

    经典动态规划合集_牛人 树形,压缩 老题

    POJ 动态规划总结 背包之01背包、完全背包、多重背包详解 Dynamic+Programming 典型的动态规划,用递归下的记忆化搜索来实现 1088 POJ 动态规划加速原理之四边形不等式 基于连通性状态压缩的动态规划问题 对一些DP...

    acm动态规划50题

    动态规划的解决方案是使用两个指针,一个从左到右扫描数组,计算当前的累计和,并保存为最大和;另一个从右到左扫描,同样计算累计和并与已知的最大和比较。通过这种方式,可以避免重复计算,将时间复杂度降低到线性...

Global site tag (gtag.js) - Google Analytics