第三章算法上机实践报告

 

1.1 问题描述

最大子段和

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

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

1.2 算法描述

a数组来存放书籍以及D数组来记录当前以i开头的最大子段和

1、若D[i+1]>0,D[i]=D[ i+1] + a[i]

2、若D[i+1]<0,D[i]=a[i]

3、根据最优子结构性质,列出递归方程式,D[ i ] = max { D[ i+1] + a[ i ] , a[ i ] }

4、同时定义max来记录D中的最大值,并用0来初始化max,因为题目要求当所给的整数均为负数时,定义子段和为0

5、输出max即为题目所求的最大子段和

 

#include <iostream>

 

using namespace std;

 

int main()

 

{

 

int a[100]={0};

 

int D[100]={0};

 

int max=0;

 

int n;

 

cin >> n;

 

for(int i=0; i<n ;i++)

 

cin >> a[i];

 

D[n-1]=a[n-1];

 

for(int i=n-1;i>=0;i--)

{

 

if(D[i+1]>0)

 

 D[i]=a[i]+D[i+1];

 

else

 

D[i]=a[i];

 

}

 

for(int i=n-1;i>=0;i--)

 

{

 

if(max < D[i])

 

max = D[i];

 

}

 

cout <<max;

 

}

 

1.3 问题求解:

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

D[ i ] = max { D[ i+1] + a[ i ] , a[ i ] }

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

D是一个一维数组,长度与a数组相同,我们令D[n-1]=a[n-1],从后往前填写,填写的为范围是下标0至n-1。

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

时间复杂度:n有关的for循环,故为O(n)

空间复杂度:开设了一个大小为n的数组存放当前下标的最大子段和,与n有关,故为O(n)

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

这道题一开始没有什么头绪,是看北航老师的视频才学会的,学会Di)数组的存放以及表达,用来表示某一段的最大子段和,这种分段存放的思想在后面的很多题目中都能用到。

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

1)在做动态规划的问题的时候要根据这四步来分析:1、分析问题的结构 2、建立递推关系 3、自底向上计算 4、选择最优方案

2)我们做动态规划的题目的时候是一定能写出递归方程式的,在实验课上我知道了,有些题目虽然你会写,能简单的将题目看出来,但不一定是用了动态规划的方法,所以我们一定要先写出方程式再去打代码。

3)动态规划常用于解最值问题,且该问题可以被分解成小问题有且只求解一次,如果满足这两个条件我们就可以用动态规划了。

 

posted @ 2021-10-26 20:33  陈沛林  阅读(34)  评论(0编辑  收藏  举报