算法第二章上机实践报告

#include<iostream>
using namespace std;

int maxsum(int a[],int l,int r)
{
    int sum=0;
    if(l==r)
    {
        sum=a[l]>0?a[l]:0;//如果只有一个数,小于零就置为零,反之则输出它本身
        
    }
    else{
        int mid = (l+r)/2;
        int lsum=maxsum(a,l,mid);
        int rsum=maxsum(a,mid+1,r);
        int s1=0;
        int lefts=0;
        for(int i=mid;i>=l;i--)
        {
            lefts+=a[i];
            if(lefts >s1)
            {
                s1=lefts;
            }
    }
            int s2=0;
            int rights=0;
            for(int i=mid+1;i<=r;i++)
            {
                rights+=a[i];
                if(rights>s2)
                {
                    s2=rights;
                }
            }
            
            sum=s2+s1;
            if(sum<lsum)
            {
                sum=lsum;
            }
            if(sum<rsum)
            {
                sum=rsum;
            }
        
        return sum;
    } 
     
}

int MaxSum(int n,int *a)
{
    return maxsum(a,1,n);
}
int main()
{
    int K,a[200005];
    cin>>K;
    for(int i=1;i<=K;i++)
    {
        cin>>a[i];
    }
    
    cout<<MaxSum(K,a);
    return 0;
}

 

以求最大子列和为例

一,实践题目名称:最大子列和问题

二,问题描述:

 给定K个整数组成的序列{ N​1​​ , N​2​​ , ..., N​K​​ },“连续子列”被定义为{ N​i, N​i+1​​ , ..., N​j

​​ },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:

数据1:与样例等价,测试基本正确性;

数据2:102个随机整数;

数据3:103个随机整数;

数据4:104个随机整数;

数据5:105个随机整数;

 

三,算法描述:

把数组分两半,求出左边最大子段和,右边最大子段和,以及跨两边的最大子段和,三者比较,选出最大的即可。

 

四,算法时间复杂度和空间复杂度分析

 时间复杂度:假设问题规模为n问题被划分为两个子问题,2T(N/2);合并子问题,o(N), 所以 T(N)=2T(N/2)+o(N),则时间复杂度为o(nlogn)

空间复杂度:老师,我不会分析...

 

五,心得体会

对分治法思想的理解更加深入,运用更加熟练。相比最暴力最传统的方法(所有字段和都求出来),分治法避免了重复的计算,提高了效率。

实验课那天,按照书上的代码敲出来,代码通过了,以为自己懂了,但其实当老师提问时,又回答不清晰。

只有自己理解了才可以真正的掌握知识。

 

posted @ 2020-10-06 19:02  kms115  阅读(126)  评论(0编辑  收藏  举报