算法第三章上机实践报告
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、计算顺序