最大子段和问题(这里给出三种算法)
2018-01-18 20:36
239 查看
问题描述
对于给定序列a1,a2,a3……an,寻找它的某个连续子段,使得其和最大。如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20。
(1)枚举法求解
枚举法思路如下:
以a[0]开始: {a[0]}, {a[0],a[1]},{a[0],a[1],a[2]}……{a[0],a[1],……a
}共n个
以a[1]开始: {a[1]}, {a[1],a[2]},{a[1],a[2],a[3]}……{a[1],a[2],……a
}共n-1个
……
以a
开始:{a
}共1个
一共(n+1)*n/2个连续子段,使用枚举,那么应该可以得到以下算法:
具体代码如下:
算法比较简单,所以这里不一一讲解:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int MaxSum1(int n,int *a,int &besti,int &bestj)///枚举法
{
int sum=0;
for(int i=0;i<n;i++)///总共n次
{
for(int j=i;j<=n;j++)
{
int thisSum=0;
for(int k=i;k<=j;k++)
{
thisSum+=a[k];
if(thisSum>sum)
{
sum=thisSum;
besti=i;
bestj=j;
}
}
}
}
return sum;
}
int MaxSum2(int n,int *a,int &besti,int &bestj)///对枚举法的一个改进
{
int sum=0;
for(int i=0;i<n;i++)///总共n次
{
int thisSum=0;
for(int j=i;j<=n;j++)
{
thisSum+=a[j];
if(thisSum>sum)
{
sum=thisSum;
besti=i;
bestj=j;
}
}
}
return sum;
}
int MaxSum3(int n,int *a,int &besti,int &bestj)///动态规划法
{
int sum=0,b=0;
for(int i=0;i<n;i++)///总共n次
{
for(int j=i;j<=n;j++)
{
if(b>0)
{
b+=a[j];
}
else
{
b=a[j];
}
if(b>sum)
{
9958
sum=b;
besti=i;
bestj=j;
}
}
}
return sum;
}
int main()
{
int n;
cout<<"请输入总个数n:";
cin>>n;
int a[] = {-2,11,-4,13,-5,-2};
cout<<endl<<endl<<"输出数组a为以下数:";
for(int i=0; i<n; i++)
{
cout<<a[i]<<" ";
}
int besti,bestj;
cout<<endl<<endl<<"方法MaxSum1数组a的最大连续子段和为:a["<<besti+1<<":"<<bestj+1<<"]:"<<MaxSum1(n,a,besti,bestj);
cout<<endl<<endl<<"方法MaxSum2数组a的最大连续子段和为:a["<<besti+1<<":"<<bestj+1<<"]:"<<MaxSum2(n,a,besti,bestj);
cout<<endl<<endl<<"方法MaxSum3数组a的最大连续子段和为:a["<<besti+1<<":"<<bestj+1<<"]:"<<MaxSum2(n,a,besti,bestj)<<endl<<endl<<endl;
return 0;
}
运行结果如下:
对于给定序列a1,a2,a3……an,寻找它的某个连续子段,使得其和最大。如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20。
(1)枚举法求解
枚举法思路如下:
以a[0]开始: {a[0]}, {a[0],a[1]},{a[0],a[1],a[2]}……{a[0],a[1],……a
}共n个
以a[1]开始: {a[1]}, {a[1],a[2]},{a[1],a[2],a[3]}……{a[1],a[2],……a
}共n-1个
……
以a
开始:{a
}共1个
一共(n+1)*n/2个连续子段,使用枚举,那么应该可以得到以下算法:
具体代码如下:
算法比较简单,所以这里不一一讲解:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int MaxSum1(int n,int *a,int &besti,int &bestj)///枚举法
{
int sum=0;
for(int i=0;i<n;i++)///总共n次
{
for(int j=i;j<=n;j++)
{
int thisSum=0;
for(int k=i;k<=j;k++)
{
thisSum+=a[k];
if(thisSum>sum)
{
sum=thisSum;
besti=i;
bestj=j;
}
}
}
}
return sum;
}
int MaxSum2(int n,int *a,int &besti,int &bestj)///对枚举法的一个改进
{
int sum=0;
for(int i=0;i<n;i++)///总共n次
{
int thisSum=0;
for(int j=i;j<=n;j++)
{
thisSum+=a[j];
if(thisSum>sum)
{
sum=thisSum;
besti=i;
bestj=j;
}
}
}
return sum;
}
int MaxSum3(int n,int *a,int &besti,int &bestj)///动态规划法
{
int sum=0,b=0;
for(int i=0;i<n;i++)///总共n次
{
for(int j=i;j<=n;j++)
{
if(b>0)
{
b+=a[j];
}
else
{
b=a[j];
}
if(b>sum)
{
9958
sum=b;
besti=i;
bestj=j;
}
}
}
return sum;
}
int main()
{
int n;
cout<<"请输入总个数n:";
cin>>n;
int a[] = {-2,11,-4,13,-5,-2};
cout<<endl<<endl<<"输出数组a为以下数:";
for(int i=0; i<n; i++)
{
cout<<a[i]<<" ";
}
int besti,bestj;
cout<<endl<<endl<<"方法MaxSum1数组a的最大连续子段和为:a["<<besti+1<<":"<<bestj+1<<"]:"<<MaxSum1(n,a,besti,bestj);
cout<<endl<<endl<<"方法MaxSum2数组a的最大连续子段和为:a["<<besti+1<<":"<<bestj+1<<"]:"<<MaxSum2(n,a,besti,bestj);
cout<<endl<<endl<<"方法MaxSum3数组a的最大连续子段和为:a["<<besti+1<<":"<<bestj+1<<"]:"<<MaxSum2(n,a,besti,bestj)<<endl<<endl<<endl;
return 0;
}
运行结果如下:
相关文章推荐
- 三种算法求最大子段和问题——Java实现
- 三种算法实现最大子段和问题(Java实现)
- 三种算法求最大子段和问题——Java实现
- 【算法设计】最大子段和问题
- 【算法】最大子段和问题
- 最大子矩阵问题;枚举行的组合,然后利用一维最大子段和的DP算法;
- 从最大子段和问题看算法的优化问题
- 0013算法笔记——【动态规划】最大子段和问题,最大子矩阵和问题,最大m子段和问题
- 从最大子段和问题看算法的优化问题
- 最大子段和问题的四种算法(暴力法、优化后的暴力法、分治算法、动态规划算法)
- 使用三种算法解决从键盘输入两个整数,输出两个整数的最大公约数的问题
- 从最大子段和问题看算法的优化问题
- [算法]最大子段和问题
- 从最大子段和问题看算法的优化问题
- 【算法学习笔记】19.算法设计初步 最大子列和问题的三种方法
- 【算法设计】最大子段和问题解析(对应算法第三题)
- 【算法学习笔记】19.算法设计初步 最大子列和问题的三种方法
- 【算法设计】最大子段和问题解析(对应算法第三题)
- 【算法设计与分析】最大子段和问题
- 【算法设计】最大子段和问题解析(对应算法第三题)