Java教程

算法第三章实践报告

本文主要是介绍算法第三章实践报告,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、实践题目名称

最大子段和

二、问题描述

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

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

三、算法描述

分析题目,要求最大子段和,用N表示输入数组,S[i]记录以下标i结尾的子段和,S[i]的最大值即为最大子段和,而S[i]会依赖前面的子问题S[i - 1],根据动态规划,即递归方程为:S[i] = max {S[i - 1] + N[i], N[i]},边界条件即S[1] = N[1]。用k记录数组种负数个数,如果k会等于n及输入全为负数,输出0,否则,进行动态规划,用maxsum记录最大子段和即S[i]的最大值,填数组S过程中更新maxsum的值,填完数组S,得到的maxsum就是最大子段和,输出maxsum

四、问题求解

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

S[i] = max {S[i - 1] + N[i], N[i]} (1 <= i <= n)

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

一维S[i]数组,从S[1]填至S[n],从左至右

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

关键语句在一个for循环中,所以时间复杂度为 T(n) = O(n)

只需记录输入数的数组N和记录子段和的数组S,即空间复杂度为O(n)

五、心得体会

粗心导致的问题:一开始设置数组N以及存储子段和的数组S的大小是n,然后两个数组都是从1开始存的,就造成了不够存的溢出错误,后面修改大小为n + 1就正确了

这题用到了动态规划的思想,通过pta的几道题练习后,我对动态规划进一步了解了

动态规划总结

哪些问题可以使用动态规划

  1. 最优子结构(必须有)

    原问题的解包含子问题的解

  2. 子问题重叠(不是必须有的)

    许多子问题会重复求解,用表格存储子问题的解,要用时在查找

    注:子问题不重叠既可以使用分治法,也可以用动态规划。但重叠时用分治法重复求解子问题导致效率低下

  3. 无后效性(必须有)

    自下而上地求解,当前子问题求解只与下方的子问题有关

求解分析步骤

有向无环图

  1. 状态

    分析当前状态

  2. 阶段

    根据拓扑序划分阶段,某几个子问题求解后才能求解下一个子问题,它们就分为不同阶段

  3. 决策

    写出状态转移方程 == 递归方程

 

这篇关于算法第三章实践报告的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!