算法第三章实践报告
算法第三章实践报告
1.1问题描述--最大子段和
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。要求算法的时间复杂度为O(n)。
1.2 算法描述
动态规划法
定义的变量(5个):3个整数型——n用于记录整数个数;maxnum用于记录动态变化的最大和值;nownum用于记录当前的和&1个整型数组——a[1000]用于储存n个整数。
Int nownum = 0;
//nownum初始化为0,以便在循环求以第i个元素为首的最长子列和中可以以第1个元素(即数组中的-2)开始求。
for (int i=0; i<n; i++){
if(nownum<0) //递归方程中的b[i-1]<=0,b[i] = a[i]
nownum = a[i];
else
nownum = nownum+a[i]; //递归方程中的b[i-1] >0,b[i] = b[i-1]+a[i]
if(maxnum < nownum)
maxnum = nownum; //递归方程中的max(b[i-1]+a[i], a[i])
}
cout << maxnum;
1.1.1 根据最优子结构性质,列出递归方程式
b[i] = max(b[i-1]+a[i], a[i])
b[i]表示以a[i]为开头的最大字段和;
max(b[i-1]+a[i], a[i]) 表示通过比较大小来求和,若b[i-1]<=0,b[i] = a[i];b[i-1] >0,b[i] = b[i-1]+a[i]。
1.1.2 给出填表法中表的维度、填表范围和填表顺序。
一维
-2 |
11 |
-4 |
13 |
-5 |
-2 |
a[i]数组
-2 |
11 |
7 |
20 |
15 |
13 |
d[i]数组
1.1.3 分析该算法的时间和空间复杂度
时间复杂度:n 一重循环
空间复杂度:n
1.3 心得体会(对本次实践收获及疑惑进行总结)
相比于上一章的分而治之,动态规划让我觉得做题难度up了。事实上这两种算法是相似的,基本思想:将一个大问题分解成若干个小问题,但有时候动态规划得到的子问题可能不是相互独立的。在本题求解过程中,我首先联想到的是郑老师上课讲的矩阵划分,本题又恰好是连续型的求和,因此在首次思考,寻找规律时,我用()把数组分成两组(-2...-5)-2,若()内的和<=0则置零直接加后面的数,当后面的数<0,整个和为0。想要知道()的和又要划分,一直划分到(-2)11。划分好后就要根据题目要求找限制条件——a[i]<=0,且b[i-1]<0,b[i]=a[i]。通过这次实践,我对动态规划解题思路更熟悉点了,但是还是掌握的不算好,需要再多练练题目。