算法第三章实践报告
实践题目:
问题描述:
该问题目标是求出最大子段和,比如说样例中,最大子段和就为11+(-4)+13=20。
注意:最大子段和必须是连续的!不是最大子串和!
算法描述:
该题使用动态规划算法。
递归方程为:
(不会打数学公式,此图来源于网上):
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXLENGTH 205
int arr[MAXLENGTH];
//寻找最大子段和算法
//arr[i]代表从第一个到第i个元素的当前最大子段和
void findMaximun(int arr[], int n) {
for (int i = 1; i <= n; i++) {
//假如第一个元素为负数的话,将其对应的数组元素初始化为0(最大和肯定不会算上第一个的负数)
if (i == 1 && arr[i] < 0) {
arr[i] = 0;
}
else {
//如果arr[i] + arr[i - 1] > 0,当前的子段和还可以再增加,所以将arr[i]赋值
if (arr[i] + arr[i - 1] > 0) {
arr[i] = arr[i] + arr[i - 1];
}
}
}
}
int main() {
int n,max;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
}
findMaximun(arr, n);
max = 0;
//遍历以取得最大值
for (int i = 1; i <= n; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
cout << max;
system("pause");
return 0;
}
算法时间及空间复杂度分析:
时间复杂度:
在findMaximun函数中,只执行了一次循环就取得了最大值。因此时间复杂度为O(n)。
空间复杂度:
并未开辟新空间,所以空间复杂度和数组长度n有关,空间复杂度为O(n)。
心得:
关于动态规划的特征:
- 动态规划一般用来寻找最优解
- 动态规划递归求出最优解,所以一定要先写出递归方程。
- 一般用自底向上的方法计算。
参考:
https://blog.csdn.net/fxkcsdn/article/details/81291465
https://blog.csdn.net/sunkun2013/article/details/49963691