揭露动态规划真面目——算法第三章上机实践报告

算法第三章上机实践报告

一、        实践题目

7-2 最大子段和 (40 )

给定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

二、        问题描述

输入一个数,表示接下来输入的数组元素个数,第二行输入所有元素,求出他们的最大子段和(如果都是负数就输出0)。

相当于,从第一个数开始,往后加数,如果是正数就说明这个子段是“有用的”反之“对最大子段没有贡献”。只要判断每次以最后一个数为结尾和前一个数结尾的大小,取大的,递归赋给一个记录用的变量即可。

三、        算法描述

1、动态规划

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

dp[i]=max(a[i],dp[i-1]+a[i]);

maxn=max(maxn,dp[i]);

}

从第一个数字开始,先赋初值0给dp数组和记录用的变量maxn,dp[i]为以第i个数字结尾的最大子段和。每次dp[i]都取数组第i个数和dp[i-1]加上目前指向的这个数中较大的那个(意义在于,如果目前指向的那个数比dp[i-1]加上目前指向的这个数还大,说明之前的子段和是负数,没有贡献不取)。而“maxn=max(maxn,dp[i])”就是筛选掉负数,若为正,取最大的子段和(dp数组储存着分别以每个数为结尾的最大子段和)。

2、判断输出

if(maxn) cout<<maxn<<endl;

else cout<<0<<endl;

若maxn为正数则得到最大子段和输出,否则(maxn为0或负数),数组全为负数或者最大子段和即为0,按要求输出0。

3、完整代码

#include<iostream>

#include<algorithm>

using namespace std;

int n,maxn;

int a[10005],dp[10005];

int main(){

cin>>n;

for(int i=1;i<=n;i++)

cin>>a[i];

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

dp[i]=max(a[i],dp[i-1]+a[i]);

maxn=max(maxn,dp[i]);

}

if(maxn) cout<<maxn<<endl;

else cout<<0<<endl;

return 0;

}

四、        算法时间及空间复杂度分析

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

dp[i]=max(a[i],dp[i-1]+a[i]);

maxn=max(maxn,dp[i]);

}

循环递归调用n次,动态规划问题一般时间复杂度为O(n)或者O(n^2),显然在这里是O(n);

解这道题中,用到了dp数组和maxn变量作为辅助,空间复杂度同样为O(n)。

五、        心得体会

抓住问题的关键,理清解题思路,一道看似“很难”的题目其实很“简单”。尤其是动态规划问题,不断动态地自下而上添加新的元素得到结果,最后解决问题。

虽然思路想出来了,有时候还是不知道怎么下手去敲代码,反映了自己做题数量太少,打代码地时间和次数太少,还停留在空想地阶段,这是一个大问题,亟待改正和提高。

队友很强,有时候会比较依赖队友,应该先自己思考后再与队友讨论才能够有所提高。

原文地址:https://www.cnblogs.com/990924991101ywg/p/11706832.html

时间: 2024-11-24 21:38:06

揭露动态规划真面目——算法第三章上机实践报告的相关文章

算法第三章上机实践报告——动态规划

1.实践题目 7-1 数字三角形 (30 分) 给定一个由 n行数字组成的数字三角形如下图所示.试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大. 输入格式: 输入有n+1行: 第 1 行是数字三角形的行数 n,1<=n<=100. 接下来 n行是数字三角形各行中的数字.所有数字在0..99 之间. 输出格式: 输出最大路径的值. 输入样例: 在这里给出一组输入.例如: 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6

算法第三章上机实践报告

实践题目 7-1 数字三角形 (30 分) 给定一个由 n行数字组成的数字三角形如下图所示.试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大. 输入格式: 输入有n+1行: 第 1 行是数字三角形的行数 n,1<=n<=100. 接下来 n行是数字三角形各行中的数字.所有数字在0..99 之间. 输出格式: 输出最大路径的值. 输入样例: 在这里给出一组输入.例如: 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5

算法第三章上机实践报告之数字三角形

1.实践题目 7-1 数字三角形 (30 分) 给定一个由 n行数字组成的数字三角形如下图所示.试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大. 输入格式: 输入有n+1行: 第 1 行是数字三角形的行数 n,1<=n<=100. 接下来 n行是数字三角形各行中的数字.所有数字在0..99 之间. 输出格式: 输出最大路径的值. 输入样例: 在这里给出一组输入.例如: 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6

贪心算法?我全都要!——算法第四章上机实践报告

算法第四章上机实践报告 一.        实践题目 4-1 程序存储问题 (90 分) 设有n 个程序{1,2,…, n }要存放在长度为L的磁带上.程序i存放在磁带上的长度是 li,1≤i≤n. 程序存储问题要求确定这n 个程序在磁带上的一个存储方案, 使得能够在磁带上存储尽可能多的程序. 对于给定的n个程序存放在磁带上的长度,计算磁带上最多可以存储的程序数. 输入格式: 第一行是2 个正整数,分别表示文件个数n和磁带的长度L.接下来的1行中,有n个正整数,表示程序存放在磁带上的长度. 输出

『嗨威说』算法设计与分析 - PTA 数字三角形 / 最大子段和 / 编辑距离问题(第三章上机实践报告)

本文索引目录: 一.PTA实验报告题1 : 数字三角形 1.1 实践题目 1.2 问题描述 1.3 算法描述 1.4 算法时间及空间复杂度分析 二.PTA实验报告题2 : 最大子段和 2.1 实践题目 2.2 问题描述 2.3 算法描述 2.4 算法时间及空间复杂度分析 三.PTA实验报告题3 : 编辑距离问题 3.1 实践题目 3.2 问题描述 3.3 算法描述 3.4 算法时间及空间复杂度分析 四.实验心得体会(实践收获及疑惑) 一.PTA实验报告题1 : 数字三角形 1.1 实践题目: 1

算法第三章上机实践

1.实践题目 最大子段和 2.问题描述 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的子段和的最大值.当所给的整数均为负数时,定义子段和为0. 要求算法的时间复杂度为O(n). 输入格式: 输入有两行: 第一行是n值(1<=n<=10000): 第二行是n个整数. 输出格式: 输出最大子段和. 3.算法描述 int maxsum(int a[],int n) { int sum=0,k=0; for(int i=

算法第三章上机实验报告

1.实践题目 7-2 最大子段和 2.问题描述 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的子段和的最大值.当所给的整数均为负数时,定义子段和为0. 要求算法的时间复杂度为O(n). 3.算法描述 首先将数据保存到一个数组内,然后建立一个循环来遍历这些数组,定义一个sum来保存和,定义一个max来保存最大值,对于每次遍历的结果x,如果sum为负,则将sum的值更改为x,并与max做对比,若比max大则将sum的值

第三章上机实践报告

1.实践题目 7-3 编辑距离问题 2.问题描述 设A和B是2个字符串.要用最少的字符操作将字符串A转换为字符串B.这里所说的字符操作包括 (1)删除一个字符: (2)插入一个字符: (3)将一个字符改为另一个字符. 将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B). 对于给定的字符串A和字符串B,计算其编辑距离 d(A,B). 3.算法描述 填表,先给第一行赋初值,然后每个格填入它左边,正上方和左上角这三个数的最小值,最后右下角的数即为问题的解. 4.

算法第3章上机实践报告

1.实践题目  7-1 数字三角形 2.问题描述 给定一个由 n行数字组成的数字三角形如下图所示.试设计一个算法, 计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大. 3.算法描述 求以一个的数为顶至底的数字总和 等于求以这个数左边或右边的数为顶至底的数字总和的最大值加上这个数本身 得出递推方程 m[i][j]=max( m[i+1][j], max[i+1][j+1] )+a[i][j] 从下至上填表 4.算法时间及空间复杂度分析 双重循环对维