最大子段和问题(C/C++)
一、蛮力法
#include<iostream>
using namespace std;
int MaxSum(int a[], int n)
{
int i,j;
int maxSum = 0;
for(i = 0; i < n; i++)
{
int sum = 0;
for(j = i; j < n; j++)
{
sum += a[j];
if(sum > maxSum)
{
maxSum = sum;
}
}
}
return maxSum;
}
int main()
{
int a[20];
int n,SUM=0;
cout<<"请输入序列的长度:";
cin>>n;
cout<<"请输入序列中的数值:"<<endl;
for(int i=0; i<n; i++)
{
cin>>a[i];
}
SUM=MaxSum(a,n);
cout<<"最长字段和为:";
cout<<SUM<<endl;
return 0;
}
二、分治法
#include<iostream>
using namespace std;
int MaxSum(int a[],int left,int right) //求序列a[left]~a[right]的最大字段和
{
int sum=0,midSum=0,leftSum=0,rightSum=0;
int center,s1,s2,lefts,rights;
if(left==right) //如果序列长度为1,直接求解
{
sum=a[left];
}
else
{
center=(left+right)/2; //划分
leftSum=MaxSum(a,left,center); //对应情况一,递归求解
rightSum=MaxSum(a,center+1,right); //对应情况二,递归求解
s1=0; //以下对应情况三,先求解s1
lefts=0;
for(int i=center; i>left; i--)
{
lefts+=a[i];
if(lefts>s1)
s1=lefts;
}
s2=0; //再求解s2
rights=0;
for(int j=center+1; j<=right; j++)
{
rights+=a[j];
if(rights>s2)
s2=rights;
}
midSum=s1+s2; //计算情况三的最大子段和
if(midSum<leftSum) //合并解,取较大者
sum=leftSum;
else
sum=midSum;
if(sum<rightSum)
sum=rightSum;
}
return sum;
}
int main()
{
int a[20];
int n,SUM=0;
cout<<"请输入序列的长度:";
cin>>n;
cout<<"请输入序列中的数值:"<<endl;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
SUM=MaxSum(a,0,n-1);
cout<<"最长字段和为:";
cout<<SUM<<endl;
return 0;
}
三、动态规划法
#include<iostream>
#include<cstdio>
using namespace std;
void MaxSum(int a[], int n){
int b[n];
int i, j, s = n - 1;
int maxSum = 0;
b[0] = a[0]; //只有一个数时 最大子段和是其本身
for(i = 1; i < n; i++){
if(b[i - 1] > 0)
b[i] = b[i - 1] + a[i];
else{ //前面的值小于0 直接从当前原数组开始
b[i] = a[i];
}
}
/* printf("\n\n动态规划法 打印b数组:");
for(i = 0; i < n; i++){
printf("%d ", b[i]);
}
printf("\n");
*/
for(j = 0; j < n; j++){
if(b[j] > maxSum){
s = j;
maxSum = b[j];
}
}
cout<<"动态规划法求出最大字段和为:"<<maxSum<<endl;
for(i = s-1; i >= 0; i--){
if(b[i] <= 0)
break;
}
cout<<"打印最大子段:"<<endl;
for(i = i + 1; i <= s; i++){
cout<<a[i]<<" ";
}
}
int main()
{
int a[20];
int n,SUM=0;
cout<<"请输入序列的长度:";
cin>>n;
cout<<"请输入序列中的数值:"<<endl;
for(int i=0; i<n; i++)
{
cin>>a[i];
}
MaxSum(a,n);
return 0;
}