1.采用简单dp与分治策略(与0比较)
每输入一个数字进行比较与求和,该次求和与上一次求和值进行比较并完成相应的替换,
上一次值与当前输入元素进行比较。
#include
#include
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int summax,sum;
int i,n,num;
while(scanf("%d",&n)!=EOF)
{
summax=0;
sum=0;
for(i=0;i
2.第一版的等价版
#include
using namespace std;
int main()
{
int max,n,now,maxstart,maxend,sum,sumstart,first;
while(cin>>n&&n)
{
cin>>now;
max=maxstart=maxend=first=now;
sum=sumstart=now;
for(int j=2;j<=n;j++)
{
cin>>now;
if(now>sum+now)
{
sumstart=now,sum=now;
}
else sum+=now;
if(sum>max)
{
max=sum;maxstart=sumstart,maxend=now;
}
}
if(max<0) cout<<"0"<
3.另一种比较好的算法
int _tmain(int argc, _TCHAR* argv[])
{
int n;//存储所输入的数组长度
scanf("%d", &n);
int* b = (int*)malloc(n*sizeof(int));//存储所出入的数组
for (int i = 0; i < n; i++)
{
scanf("%d", &b[i]);
}
int sum=0;//最大子数列和
//寻找最大子数列
for (int i = 0; i < n; i++)
{
int thisSum = 0;//当前数列
for (int j = i; j < n; j++)
{
thisSum += b[j];
if (thisSum>sum)
{
sum = thisSum;
}
}
}
if (sum < 0)
{
printf("%d",0);
}else{
printf("%d", sum);
}
system("pause");
return 0;
}
4、暴力求解
#include "stdafx.h"
//暴力法求最大子数组和问题
int _tmain(int argc, _TCHAR* argv[])
{
int A[8] = { -6, 10, -5, -3, -7, -1, -1 };
int array_length = sizeof(A) / sizeof(A[0]);//数组大小
int sum = -10000;//记录子数组的和
int low;//记录子数组的底
int height;//记录子数组的高
for (int i = 0; i < array_length; i++)
{
for (int j = i ; j < array_length; j++)
{
int subarraysum=0;//所遍历出来的子数组的和
//计算遍历的子数组之和
for (int k = i; k <= j; k++)
{
subarraysum += A[k];
}
//找出最大的子数组
if (subarraysum>sum)
{
sum = subarraysum;
low = i;
height = j;
}
}
}
printf("%d %d %d", low, height,sum);//将结果打印出来
getchar();
return 0;
}
5、分治法
#include "stdafx.h"
//分治法求最大子数组和问题
struct PositioASum {
int low;
int high;
int sum;
};
//寻找包含中点位置的最大子数组函数
PositioASum MaxCrossingSubarray(int a[], int low, int mid, int high)
{
//求中点左边的最大值和最大位置
int maxLeft;//记录左边的最大位置
int maxSumLeft=-10000;//记录左边的最大和
int sumLeft=0;
for (int i = mid; i >= low; i--)
{
sumLeft += a[i];
if (sumLeft > maxSumLeft)
{
maxSumLeft = sumLeft;
maxLeft = i;
}
}
//求中点右边的最大值和最大位置
int maxRight=mid+1;//记录右边的最大位置
int maxSumRight = -10000;//记录右边的最大和
int sumRight = 0;//记录右边子数列的和
for (int i = mid+1; i <= high; i++)
{
sumRight += a[i];
if (sumRight > maxSumRight)
{
maxSumRight = sumRight;
maxRight = i;
}
}
PositioASum ps;
ps.low = maxLeft;
ps.high = maxRight;
ps.sum = maxSumLeft + maxSumRight;
return ps;
}
//分治法
PositioASum FindMaxSubArray(int a[], int low, int high)
{
if (low == high)
{
PositioASum ps;
ps.low = low;
ps.high = high;
ps.sum = a[low];
return ps;
}
else{
int mid = (low + high) / 2;
PositioASum left = FindMaxSubArray(a, low, mid);
PositioASum right = FindMaxSubArray(a, mid + 1, high);
PositioASum cross = MaxCrossingSubarray(a, low, mid, high);
if (left.sum >= cross.sum && left.sum >= right.sum)
{
return left;
}
else if (right.sum >= left.sum && right.sum >= cross.sum)
{
return right;
}else{
return cross;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int A[8] = {-1,0,0,0,-1};
PositioASum result = FindMaxSubArray(A, 0, 4);
printf("%d %d %d", result.low, result.high, result.sum);//将结果打印出来
getchar();
return 0;
}