题目:
给定一个整数序列,a0, a1, a2, …… , an(项可以为负数),求其中最大的子序列和。如果所有整数都是负数,那么最大子序列和为0;
例如:对于序列-2, 11, -4, 13, -5, –2。 所求的最大子序列和为20(从11到13,即从a1到a3)。
暴力法:
#include<cstdio>
#include<iostream>
#define N 100
using namespace std;
int A[N];
int arraylength;
int MaxSubArray()
{
int currentSum,maxSum=A[0];
for(int i=0;i<arraylength;i++)
{
for(int j=i;j<arraylength;j++)
{
currentSum=0;
for(int k=i;k<=j;k++)
{
currentSum+=A[k];
}
if(currentSum>maxSum)
maxSum=currentSum;
}
}
return maxSum;
}
int main()
{
cin>>arraylength;
for(int i=0;i<arraylength;i++)
{
cin>>A[i];
}
cout<<MaxSubArray()<<endl;
}
分治法:
#include<cstdio>
#include<iostream>
#define N 100
using namespace std;
int A[N];
int arraylength;
int MaxSubArray(int from,int to)
{
if(from==to) return A[from];
int middle=(from+to)/2;
int left=MaxSubArray(from,middle); //完全在左边
int right=MaxSubArray(middle+1,to); //完全在右边
//跨立在中间
int leftMaxSum=A[middle],currentLeftSum=A[middle];
//向中间前扫
for(int i=middle-1;i>=from;i--)
{
currentLeftSum+=A[i];
leftMaxSum=max(currentLeftSum,leftMaxSum);
}
int rightMaxSum=A[middle+1],currentRightSum=A[middle+1];
//向中间后扫
for(int i=middle+2;i<to;i++)
{
currentRightSum+=A[i];
rightMaxSum=max(currentRightSum,rightMaxSum);
}
int Max=max(right,left);
Max=max(Max,leftMaxSum+rightMaxSum);
return Max;
}
int main()
{
cin>>arraylength;
for(int i=0;i<arraylength;i++)
{
cin>>A[i];
}
cout<<MaxSubArray(0,arraylength)<<endl;
}
动态规划:
#include<cstdio>
#include<iostream>
#define N 100
using namespace std;
int A[N];
int arraylength;
int MaxSubArray()
{
int sum=A[0];
int result=A[0];
for(int i=1;i<arraylength;i++)
{
if(sum>0) sum+=A[i];
else sum=A[i];
result=max(sum,result);
printf("%d %d\n",sum,result);
}
return result;
}
int main()
{
cin>>arraylength;
for(int i=0;i<arraylength;i++)
{
cin>>A[i];
}
cout<<MaxSubArray()<<endl;
}