全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案汇总

题目:Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous subsequence is defined to be { N​i​​, N​i+1​​, ..., N​j​​ } where 1≤i≤j≤K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (≤10000). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4

给定一个K整数序列{ N1,N2,…,Nk }。连续子序列定义为{ Ni,Ni+1,…,Nj },其中1≤i≤j≤K。最大子序列是具有最大元素和的连续子序列。例如,给定序列{-2,11,-4,13,-5,-2},其最大子序列为{11,-4,13},最大和为20。

现在您应该找到最大和,以及最大子序列的第一个和最后一个数

输入规格:

每个输入文件包含一个测试用例。每个案件都有两行。第一行包含正整数K(≤10000)。第二行包含K个数字,用空格隔开。

输出规格:

对于每个测试用例,在一行中输出最大和,以及最大子序列的第一个和最后一个数字。数字必须用一个空格隔开,但行尾不能有多余的空格。如果最大子序列不唯一,则输出索引i和j最小的子序列(如示例所示)。如果所有K个数都是负数,那么它的最大和被定义为0,你应该输出整个序列的第一个和最后一个数。

解答:

这个题乍看一下感觉和找最大子列问题的难度差不多,只是在得到最大子列的同时还得把最大子列的前后索引保存下来。

我们思考一下在线处理算法,

//寻找最大子列
int findMaxSubSeq(int A[],int N) {int ThisSum,MaxSum;int i;ThisSum = MaxSum = 0;for(i=0;i<N;i++){ThisSum += A[i];//向右累加if(ThisSum>MaxSum)MaxSum = ThisSum;//发现更大和则更新当前结果else if(ThisSum<0)//当前子列和为负ThisSum = 0;//则不能使后面的部分和增大,抛弃之}return MaxSum;
}

在线处理算法是从头遍历到末尾,所以复杂度为N。考虑如下列表:

我们发现若要记录最大子列的右边的索引会很简单,只需要在 if(ThisSum>MaxSum) 判断成功后让当前的i更新为右边的索引即可。

如此做,我们逆转一下思维:从左往右遍历,找到的是最大子列的右边索引,我们从右往左遍历,不就能找到最大子列的左索引了吗?

有个细节:当我们使用上面的数据时,

-10 1 2 3 4 -5 -23 3 7 -21

有两组最大子列,一个是 1 2 3 4 ,另一个是 3 7,而我们需要打印的是第一个子列,所以从右往左遍历的时候我们应该从找到的最大子列的右索引开始往左遍历,而不是从整个数列的最右边往左遍历。

#include<iostream>
using namespace std;
//寻找最大子列
int findMaxSubSeq(int A[],int N,int &left,int &right) {int ThisSum,MaxSum;int i;ThisSum = MaxSum = 0;for(i=0;i<N;i++){ThisSum += A[i];//向右累加if(ThisSum>MaxSum){MaxSum = ThisSum;//发现更大和则更新当前结果right = i;}  else if(ThisSum<0)//当前子列和为负ThisSum = 0;//则不能使后面的部分和增大,抛弃之}ThisSum = MaxSum = 0;for(i=right;i>=0;i--){ThisSum += A[i];//向左累加if(ThisSum>MaxSum){MaxSum = ThisSum;//发现更大和则更新当前结果left= i;}  else if(ThisSum<0)//当前子列和为负ThisSum = 0;//则不能使后面的部分和增大,抛弃之}  return MaxSum;
}int main(){int b[1000000] = {};int num,left,right;cin>>num;for(int i = 0;i<num;i++){cin>>b[i];}int xx = findMaxSubSeq(b,num,left,right);cout<<xx<<" "<<b[left]<<" "<<b[right];return 0;
}

但是提交以后出现了一点问题:

好吧漏题了。

全都是负数会出现什么情况呢?即最后的和会等于0,因为没有任何值加进来。想象一下,只要里面有一个正数,最大子列和就不可能为0。

然后有负数和0的情况,也就是说得把0给挑出来,那就干脆设置一个更小的初始MaxSum=-1,-1是最小的负数,这样,只要检测到0,ThisSum就比-1大。

#include<iostream>
using namespace std;
using std::cout;
using std::cin;
//寻找最大子列
int findMaxSubSeq(int A[], int N, int &left, int &right) {int ThisSum, MaxSum;int i;ThisSum = 0;MaxSum = -1;for (i = 0;i<N;i++) {ThisSum += A[i];//向右累加if (ThisSum>MaxSum) {MaxSum = ThisSum;//发现更大和则更新当前结果right = i;}else if (ThisSum<0)//当前子列和为负ThisSum = 0;//则不能使后面的部分和增大,抛弃之}ThisSum = 0;MaxSum = -1;for (i = right;i >= 0;i--) {ThisSum += A[i];//向左累加if (ThisSum>MaxSum) {MaxSum = ThisSum;//发现更大和则更新当前结果left = i;}else if (ThisSum<0)//当前子列和为负ThisSum = 0;//则不能使后面的部分和增大,抛弃之}if (MaxSum < 0) {MaxSum = 0;left = 0;right = N - 1;}return MaxSum;
}
/*
17
-10 -1 -2 -3 0 0 0 0 3 -2 4 -5 0 -23 -3 -7 -21
*/
int main() {int b[10000] = {};int num, left, right;cin >> num;for (int i = 0;i<num;i++) {cin >> b[i];}int xx = findMaxSubSeq(b, num, left, right);cout << xx << " " << b[left] << " " << b[right];//cout <<endl<< xx << " " << left << " " << right<<endl;system("pause");return 0;
}

之后除了“最大和前面有一段是0”以外其他都正确了。

这个最大和前面有一段是0是什么鬼?

难道要把前面的0也给输出了?

行吧,试了好多次,发现不止这样,

比如如下数据:

17
-10 -1 -2 -3 0 0 3 -3 3 -2 4 0 0 -5 0 -23 -3 -7 -21

竟然是输出5 0 4,因为3 -2 4 前面有一个3和-3,加起来为0,所以也放到了最大子列里面(我觉得应该是题目用的编译器的bug)同时前面的0也都放到了最大子列里面。于是我们把向左遍历里面判断的大于号改为大于等于这次提交以后全部正确

#include<iostream>
using namespace std;
using std::cout;
using std::cin;
//寻找最大子列
int findMaxSubSeq(int A[], int N, int &left, int &right) {int ThisSum, MaxSum;int i;ThisSum = 0;MaxSum = -1;for (i = 0;i<N;i++) {ThisSum += A[i];//向右累加if (ThisSum>MaxSum) {MaxSum = ThisSum;//发现更大和则更新当前结果right = i;}else if (ThisSum<0)//当前子列和为负ThisSum = 0;//则不能使后面的部分和增大,抛弃之}ThisSum = 0;MaxSum = -1;for (i = right;i >= 0;i--) {ThisSum += A[i];//向左累加if (ThisSum>MaxSum) {MaxSum = ThisSum;//发现更大和则更新当前结果left = i;}else if (ThisSum<0)//当前子列和为负ThisSum = 0;//则不能使后面的部分和增大,抛弃之}if (MaxSum < 0) {MaxSum = 0;left = 0;right = N - 1;}return MaxSum;
}int main() {int b[10000] = {};int num, left, right;cin >> num;for (int i = 0;i<num;i++) {cin >> b[i];}int xx = findMaxSubSeq(b, num, left, right);cout << xx << " " << b[left] << " " << b[right];//cout <<endl<< xx << " " << left << " " << right<<endl;system("pause");return 0;
}

算法 Maximum Subsequence Sum 2004年浙江大学计算机专业考研复试真题相关推荐

  1. 计算机学硕考研复试编程能力,苏州大学计算机学硕专业考研复试真题

    苏州大学计算机相关的专业有计算机科学与技术和软件工程,这两个专业的分数线是不一样的.新东方在线整理了苏州大学计算机科学与技术专业学硕考研复试真题,以及复试经验分享. 英语一共4道题目: 第一题:用英语 ...

  2. 计算机专业考研复试上机算法学习

    计算机专业考研复试上机算法学习 这篇博客是博主在准备可能到来的线下上机复试基于王道机试指南的学习,将各道习题链接和代码记录下来,这篇博客权且当个记录. 文章目录 计算机专业考研复试上机算法学习 1.S ...

  3. 2019年研究生入学考试北京理工大学计算机专业基础813真题回忆

    2019年计算机专业基础813真题回忆 数据结构部分 一.填空题 1.L是单向循环链表的指向头结点的指针,判断链表是否为空的条件是______ 2.一颗排序二叉树有n个结点,深度为d,则插入一个结点的 ...

  4. 云南计算机专业知识真题,2014年云南省事业单位考试专计算机专业知识模拟真题.doc...

    2014年云南省事业单位考试专计算机专业知识模拟真题 1 在Word中替换的快捷键是____. A.CTRL+F B.CTRL+H C.CTRL+S D.CTRL+P 2 在Word中打印的快捷键是_ ...

  5. 安徽大学计算机数据库基础知识,ahu: 安徽大学计算机专业【初试真题】 - 计算机专业基础(数据结构,操作系统)【复试真题】 - 计算机专业综合(计算机组成原理,数据库原理)...

    ahu 安徽大学计算机专业 [初试真题] --->计算机专业基础(数据结构,操作系统) 初试资料我没时间弄,等你们考上学弟学妹的弄吧 [复试真题] --->计算机专业综合(计算机组成原理, ...

  6. 考研计算机相关的复试自我介绍,计算机专业考研复试英文自我介绍模板

    <计算机专业考研复试英文自我介绍模板>由会员分享,可在线阅读,更多相关<计算机专业考研复试英文自我介绍模板(1页珍藏版)>请在人人文库网上搜索. 1.计算机专业考研复试英文自我 ...

  7. 计算机复试 英文介绍,计算机专业考研复试英文自我介绍模板(1页)-原创力文档...

    计算机专业考研复试英文自我介绍模板 Good morning,deer professors.I am glad to be here for this interview. My name is X ...

  8. 计算机专业考研复试(前沿知识篇)

    文章目录 前言 高频问题 1.人工智能的理解 人工智能包括六个方面: 2.神经网络 3 .机器学习--一种实现人工智能的方法 机器学习与大数据的高度耦合 区分机器.深度.强化学习 4.深度学习 5.数 ...

  9. 19吉大吉林大学计算机学院软件学院人工智能学院考研复试真题

    以下是复试题 19计学: 1:n个数,找出现次数最多的数,如果有次数最多并且相同的数,则返回较小的那个. 2:一个字符串,判断括号是否成对出现. 3:判断单向链表是否有环. 4:找一个序列中,最长的单 ...

最新文章

  1. HLG 1539 选课
  2. connect 超时
  3. 一篇文章让你真正了解Java
  4. spring5.0.2中文官网文档pdf
  5. java面试关于ssh的_[Java教程]ssh面试题
  6. 反射进行.newInstance()方法,报错Caused by: java.lang.NoSuchMethodException:XXXX.<init>()
  7. 重装系统——Win10系统U盘启动盘制作教程(MSDN自带纯净版)
  8. 手机图案密码(3*3点阵)开锁次数 C++
  9. 22-5 论如何将标准中国地图矢量化并且导入arcgis中
  10. 火灾报警管理系统java,火灾报警系统开题报告
  11. 计算机教室不安风扇,多媒体教室设备常见故障及解决办法
  12. 如何快速将多个文件合并为一个文件?
  13. Flask租房项目总结
  14. star法则简历Android,优秀简历坚持STAR原则
  15. [案例4-8]模拟物流快递系统程序设计
  16. 猿圈 题库_猿圈AI考试题库 智慧在线考试宝典
  17. 政府信息化需求开启 OA办公系统平台化时代
  18. 012:vue+openlayers加载引用3种 Stamen地图(示例代码)
  19. “安超云ArSDN”荣获“信息基础设施优秀解决方案”
  20. 查询平均工资最低的部门信息

热门文章

  1. 浏览器的排行榜及详细介绍
  2. 设计模式-结构型模式-代理模式proxy
  3. 带你预测双十一成交额,只用了20行代码量预测3287亿!
  4. php里清除浮动代码,CSS中使用clearfix清除浮动的方法
  5. vue系列之----项目在ie浏览器中空白
  6. 关于打开网页弹出am.189so.cn,卸载360浏览器用其它浏览器就好了
  7. 乖,摸摸头 - 笔记
  8. google android广告异步加载,javascript 广告后加载,加载完页面再加载广告
  9. 4月15日csol服务器维护中,csol2017年2月15日更新内容一览 csol2.15更新公告
  10. 关于生活,关于感恩...