最大子段和问题蛮力法、分治法、动态规划法(C/C++)

最大子段和问题(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;
}

猜你喜欢

转载自blog.csdn.net/qq_40513088/article/details/85285449