算法第三章上机实践报告

1. 题目分析

1.1 问题描述

最大子段和

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

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

输入格式:

输入有两行:

第一行是n值(1<=n<=10000);

第二行是n个整数。

输出格式:

输出最大子段和。

输入样例:

在这里给出一组输入。例如:

6

-2 11 -4 13 -5 -2

输出样例:

在这里给出相应的输出。例如:

20

1.2 算法描述

数组D存储的是所在下标往右加的最大子段和,数组X存储每个下标所在的数值大小。根据动态规划的思想,为了解决这个问题,可以先将每个下标所在的数值与其右边的最大子段和加起来,然后用max来存储最大的那个。

1.3 问题求解

#include<iostream>

using namespace std;

 

int main(){

int n, max=0;

cin >> n;

    int D[10000]={0};

    int X[10000]={0};

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

        cin >> X[i];

    }

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

        if(D[i+1]>0)

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

        else

            D[i]=X[i];

        if(D[i]>max)

            max=D[i];

    }

    cout << max;

return 0;

}

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

  if(D[i+1]>0) D[i]=X[i]+D[i+1];

  else   D[i]=X[i];

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

维度:一维

填表范围:1到n

填表顺序:从n到1

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

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

        if(D[i+1]>0)

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

        else

            D[i]=X[i];

        if(D[i]>max)

            max=D[i];

    }

容易看出,时间复杂度为O(n)

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

通过这次实验课,明白了自己对于动态规划的理解还是不够深刻,以及递归的一些细节还不够清楚,不过经过队友和老师的点拨,有了更好的理解,也希望自己可以把这章的内容吃透!

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

我理解的动态规划,即是对一个计算量庞大且需要重复计算的问题,可以先分析其结构,然后寻找递归关系,再由下至上计算,最后找到最优解。学会了如何去使用一个类似于备忘录的东西,去解决需要重复计算的问题,以减少算法的时间。

posted on 2021-10-26 21:12  PurLinE  阅读(21)  评论(0编辑  收藏  举报