算法第三章上机实践报告

1. 问题分析

1.1 问题描述

7-1 最大子段和 (25 分)
 

给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。

要求算法的时间复杂度为O(n)。

1.2 算法描述

根据动态规划的过程,设b为记录以当前整数结尾的子段和

1、假设最后一步是在加上a[j]取到最大值,即此时 b[j]=b[j-1]+a[j] (子问题出现)

2、若b一直为非正数(<0),则定义b[j]=a[j],根据求的是最大值,因此可以写出递归方程:b[ i ] = max { b[ i-1] + a[ i ] , a[ i ] }

3、同时定义sum;来记录b中的最大值,即题目要求的最大子段和。

1.3 问题求解

#include<iostream>
using namespace std;
int maxSum(int n,int a[]){
    int sum=0;
    int b=0;
    for(int i=0;i<n;i++){
        if(b>0)
            b+=a[i];
        else
            b=a[i];
        if(b>sum)
            sum=b;
        //cout<<"第"<<i<<"次的b:"<<b<<endl;
    }
    return sum;
}
int main(){
    int n;
    int a[n];
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    cout<<maxSum(n,a)<<endl;
    
    system("pause");
    return 0;
}

 

1.1.1 根据最优子结构性质,列出递归方程式

 b[ j ] = max { b[ j-1] + a[ j ] , a[ j ] }

 

1.1.2 给出填表法中表的维度、填表范围和填表顺序。

仅需要一维数组即可记录,由递归方程 b[ j ] = max { b[ j-1] + a[ j ] , a[ j ] },可得填表范围[1,n],至左向右填表。

 

1.1.3 分析该算法的时间和空间复杂度

一个for循环,所以时间复杂度为O(n);

数组a[n],因此空间复杂度为 O(n)。

 

1.3 心得体会(对本次实践收获及疑惑进行总结)

 充分理解好原问题是否可动态规划处理。

 

2. 你对动态规划算法的理解和体会

动态规划常用于解决计数、求最大最小以及存在问题。

步骤包括:

1、确定状态

2、初始条件以及边界条件

3、计算顺序

posted @ 2021-10-23 10:39  赖晓杰  阅读(29)  评论(0编辑  收藏  举报