最大连续子序列求和(5种)

     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;
}

你可能感兴趣的:(算法之路)