给定n个数组成的序列,求其中最大子段和,并规定其中如果所有数均为负值的时候,那么最大字段和为零。
解决这样的问题需要用的算法是:分治法
基本思路:
1. 划分两个长度基本相同的子段,得出以下三种情况
2.如果最大和出现在左边,就左边最大子段和为解
3. 如果最大和出现在右边,就右边最大子段和为解
4. 如果是最大和在左子段的最右边的数组成,和右子段的最左边的数组成,那么就合并这两个子段和,得到最终的解
解决这个问题的关键:
1. 递归法,要熟悉递归机制,那么就比较好理解了
2. 如何把三种情况都很好的计算出来并且合并起来。这也是分治法思想的精要。
下面给出详细注释的程序:
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
T sectionMaxSum(vector<T>& vt, int lIndex, int rIndex)//Index range [1,n] <=> C++Index range [0, n-1]
{
T sum = T(0);
//情况0:如果只有一个元素; 也就是递归的结束条件,这也是递归算法的必要条件
//这个算法的话必然会分治到这个情况,然后再逐层退出返回递归求的结果
if(lIndex == rIndex)
{
if(vt[lIndex-1]>0) sum = vt[lIndex-1];
else sum = 0;
}
else
{
//分治,划分两个相同长度的两个子序列
int midIndex = (lIndex+rIndex)/2;
//情况1:最大子段和为左边序列的最大子段,递归求解,注意下标设计
T lSum = sectionMaxSum(vt, lIndex, midIndex);
//情况2:最大子段和为右边序列的最大子段,递归求解,
//注意:midIndex不加1的话,就会出现递归栈溢出
T rSum = sectionMaxSum(vt, midIndex+1, rIndex);
//情况3:最大子段为两个左右子段的最大子段的和
T lSubMaxSum = T(0);
T lTempSum = T(0);
for(int i = midIndex-1; i>=lIndex-1; i--)//注意:这里lIndex-1,如果是lIndex没有-1的话,
{ //会发生掉值,结果就会不正确.
lTempSum += vt[i];
if(lTempSum>lSubMaxSum) lSubMaxSum = lTempSum;
}
T rSubMaxSum = T(0);
T rTempSum = T(0);
for(int i = midIndex; i<rIndex; i++)
{
rTempSum += vt[i];
if(rTempSum>rSubMaxSum) rSubMaxSum = rTempSum;
}
//情况1,2,3中最大者为问题最终解
sum = lSubMaxSum + rSubMaxSum;
if(sum<lSum) sum = lSum;
if(sum<rSum) sum = rSum;
}
return sum;
}
void test()
{
//初始化数组
double a[18] =
{32., 12., 0.7, 5., 0.1, 0.7, 0.8,0.7, -99., 0.4, 1., 2.5, 3.6, 5., -9., 12., 19.,23.};
vector<double> vd(a, a+18);
//元序列输出
for(int j=0; j<18; j++)
{
cout<<vd[j]<<" ";
}
cout<<endl;
//调用函数
double sum = sectionMaxSum(vd, 1, vd.size());
//最大子段和输出
cout<<sum<<endl;
}
int main()
{
test();
return 0;
}
总结:
最终答案是57.7;可以用在整数和浮点数序列中。
分享到:
相关推荐
用c++实现动态规划求最大字段和,直接运行,很好的
C++的作业,最大字段和问题 分治法,程序直接用dev就能运行。求一个序列的最大子段和即最大连续子序列之和。例如序列[4, -3, 5, -2, -1, 2, 6, -2]
用动态规划法求解最大字段和问题,DEV C++环境运行,测试可用可进行多组数据测试
求一个n个数的最大字段和问题,以及对其进行输出。基本的贪心算法问题。常用与研究生算法课程。
课程的随堂作业,C语言的,用dev就能运行,萌新代码,勿喷,仅仅帮助不想写作业的朋友方便一下,反正老师也不会仔细检查的
最大字段和问题:分别用蛮力法 分治法 动态规划法去实现的!是我交给老师的实验报告!!
Java实现算法最大字段和
最大子段和问题,可参考《算法设计与分析》讲义中关于用动态规划策略求解最大子段和问题的思想设计动态规划算法。本算法用户需要输入元素个数n,及n个整数。程序应该给出良好的用户界面,输出最大子段相关信息,包括...
Description 一个长,宽,高分别是m,n,p的长方体被分割成m*n*p个小立方体。...2,基于“最大字段和”,编写二维的“最大子矩阵和”的解法。 3,基于“最大子矩阵和”,编写三维的“最大子长方体和”的解法。
对DP问题中的最大m字段和问题进行ppt演示讲解
Visual C++源代码 118 如何显示数据表多个字段合并信息Visual C++源代码 118 如何显示数据表多个字段合并信息Visual C++源代码 118 如何显示数据表多个字段合并信息Visual C++源代码 118 如何显示数据表多个字段合并...
基于Python实现字段级血缘分析项目源码.zip基于Python实现字段级血缘分析项目源码.zip基于Python实现字段级血缘分析项目源码.zip基于Python实现字段级血缘分析项目源码.zip基于Python实现字段级血缘分析项目源码.zip...
/*蛮力法 n^2 对于数组a[n],其连续的子段有 以a[0]开始的 , { a[0] }, { a[0],a[1] },{ a[0],a[1],a[2] }.....共n 个 以a[1]开始的, { a[1] }, { a[1],a[2] },{ a[1],a[2],a[3] }........ ... 以a[n]开始的,{ a[n] }...
在vc6.0下,编译通过。实现抓包,并分析各个字段。
求最大字段的三种方法——_动态规划_蛮力_分治算法
最大字段和的分治解法 最大字段和的分治解法
本文是mysql 数据库 问题一 将表一的数据导入表二...在表中插入数据时,某一字段取数据库中该字段的最大值,并+1,这个问题很多人都说用存储过程什么的解决,其实使用insert 和 select 结合就可以很好的解决这个问题啊
按照RFC3261逐步的介绍SIP协议,介绍了c和c++语言的实现,分析了osip库的使用和实现
显示数据表多个字段合并信息,C++.net源代码编写,
Visual C++源代码 165 如何在水晶报表中添加合计字段Visual C++源代码 165 如何在水晶报表中添加合计字段Visual C++源代码 165 如何在水晶报表中添加合计字段Visual C++源代码 165 如何在水晶报表中添加合计字段...