Sample Input:

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

Sample Output:

10 1 4

错误代码如下:

#include <stdio.h>int MaxSubseqSum4(int A[], int N, int* pstart, int* pend)
{int i = 0;int tempStart; //记录最大子段和位置int thisSum = 0, sum = 0;tempStart = 0;for (i = 0; i < N; i++) {thisSum += A[i];if (thisSum > sum) {sum = thisSum;*pstart = tempStart;*pend = i;} else if (thisSum < 0) {thisSum = 0;tempStart = i + 1;//每次及时更新,但不一定是最大和的首位置}}return sum;
}int main()
{int N = 0;int A[10001] = {0};int i;int flag = 0;int start, end, sum;scanf("%d", &N);for (i = 0; i < N; i++) {scanf("%d", A+i);if (*(A+i) >= 0) {flag = 1;}}if (flag == 0) { //如果序列的值全部<0printf("0 %d %d", A[0], A[N-1]);} else {sum = MaxSubseqSum4(A, N, &start, &end);printf("%d %d %d", sum, A[start], A[end]);}return 0;
}

错误提示:

异常退出???什么原因呢?

用 下面的例子可以明白

3

-1 0 0

这个测试数据代入程序,发现start,end两个变量没有被操作,而且也没有初始化,所以异常退出。

所以程序出错就是这个例子没有通过,所以必须考虑到这种情况,重新修改函数

MaxSubseqSum4

代码如下:

#include <stdio.h>int MaxSubseqSum4(int A[], int N, int* pstart, int* pend)
{int i = 0;int tempStart; //记录最大子段和位置int thisSum = 0, sum = -1;tempStart = 0;for (i = 0; i < N; i++) {thisSum += A[i];if (thisSum > sum) {sum = thisSum;*pstart = tempStart;*pend = i;} else if (thisSum < 0) {thisSum = 0;tempStart = i + 1;//每次及时更新,但不一定是最大和的首位置}}return (sum > 0 ? sum : 0);
}int main()
{int N = 0;int A[10001] = {0};int i;int flag = 0;int start, end, sum;scanf("%d", &N);for (i = 0; i < N; i++) {scanf("%d", A+i);if (*(A+i) >= 0) {flag = 1;}}if (flag == 0) { //如果序列的值全部<0printf("0 %d %d", A[0], A[N-1]);} else {sum = MaxSubseqSum4(A, N, &start, &end);printf("%d %d %d", sum, A[start], A[end]);}return 0;
}

测试结果:

上面的代码在时间上已经达到O(n),但是空间上是相当浪费的(A[10000]),而且如果数据再多了就出现了溢出的错误,针对这两点,修改代码如下:(参考了http://www.2cto.com/kf/201311/254392.html的代码)

下面是别人的优秀代码,此代码思路非常清晰简洁:

#include<iostream>
using namespace std;
int main()
{  int N;  int *input;  int i;  int begin=0, end=0, sum=0;  //最终所求的子序列的起始位置,终止位置,以及子序列和。  int tempSum=0, tempBegin=0, tempEnd=0;  //目前正在考察的子序列的起始位置,终止位置,以及子序列的和。  cin>>N;     input = new int[N];   for(i=0; i<N; i++)  cin>>input[i];  end = N-1;    for(i=0; i<N; i++)  {  if(tempSum >= 0)  {  tempSum += input[i];  tempEnd = i;  }  else {  //如果tempSum<0,那么tempSum+input[i]<input[i]  //所以此时我们要开始考察新的子序列  tempSum = 0;   tempSum += input[i];  tempBegin = i;  tempEnd = i;  }  //if(tempSum > sum) 这样写不能AC,应改为如下:  if(tempSum > sum || (tempSum == 0 && end == N-1))  //{  sum = tempSum;  begin = tempBegin;  end = tempEnd;  }         }  cout<<sum<<" "<<input[begin]<<" "<<input[end]<<endl;  return 0;
}  

下面对这段代码做数学分析:

从集合的角度,所有的子段和可以分为三类:>0, <0, =0,<0的直接就不用考虑了,>0的直接用tempSum > sum就可以处理这种情况,比较麻烦的是=0这种情况,根据题目要求,当tempSum == 0时必须更新begin,end的值,(题目中有:保证i,j都尽可能的小),但是只有第一次更新就行了,如果每次子段和为0都更新,否则就不能保证j尽可能的小了,于是有了end == N-1这个条件。如测试数据2 1 -1.

代码优化成在线方式,代码如下:

#include<iostream>
using namespace std;
int main()
{  int N;  int a;  int i;  int begin=0, end=0, sum=0;  //最终所求的子序列的起始位置,终止位置,以及子序列和。  int tempSum=0, tempBegin = 0, tempEnd=0, allBegin = 0, allEnd = 0;  //目前正在考察的子序列的起始位置,终止位置,以及子序列的和。  int flag = 0;  int allNeg = 1;cin>>N;     for(i=0; i<N; i++)  {   cin >> a;if (i == 0) { //初始化tempBegin = a;allBegin = a;}if (i == N-1) { //初始化allEnd = a;}if (a >= 0) {  //判断是否全为负数allNeg = 0;}if(tempSum >= 0)  //记录当前tempSum值{  tempSum += a;  tempEnd = a;  }  else {  tempSum = 0;   tempSum += a;  tempBegin = a;  tempEnd = a;  }if(tempSum > sum || (tempSum == 0 && flag == 0))  {  sum = tempSum;  begin = tempBegin;  end = tempEnd;flag = 1;}         }  if (allNeg == 1)cout <<  "0" << " " << allBegin <<" "<< allEnd << endl;  elsecout << sum << " " << begin << " " << end << endl;return 0;
}  

可对照上面的代码理解此代码,优化过的代码比较难读。

1007. Maximum Subsequence Sum (25)相关推荐

  1. 【PAT甲】1007 Maximum Subsequence Sum (25分),求最大字段和及区间

    problem 1007 Maximum Subsequence Sum (25分) Given a sequence of K integers { N ​1 ​​ , N ​2 ​​ , -, N ...

  2. PAT甲级--1007 Maximum Subsequence Sum (25 分)

    题目详情 - 1007 Maximum Subsequence Sum (25 分) (pintia.cn) Given a sequence of K integers { N1​, N2​, .. ...

  3. PAT甲级 -- 1007 Maximum Subsequence Sum (25 分)

    Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous subsequence is defined to ...

  4. 【测试点5】1007 Maximum Subsequence Sum (25 分)

    立志用最少的代码做最高效的表达 PAT甲级最优题解-->传送门 Given a sequence of K integers { N​1​​ , N​2​​ , -, N​K​​ }. A co ...

  5. 1007 Maximum Subsequence Sum (25 分) java 题解

    Given a sequence of K integers { N1​, N2​, ..., NK​ }. A continuous subsequence is defined to be { N ...

  6. 1007. Maximum Subsequence Sum (25)-PAT甲级真题(最大连续子序列和、动态规划dp)

    Given a sequence of K integers { N1, N2, -, NK }. A continuous subsequence is defined to be { Ni, Ni ...

  7. PAT A 1007. Maximum Subsequence Sum (25)

    原题 Given a sequence of K integers { N1, N2, ..., NK }.  A continuous subsequence is defined to be { ...

  8. 1007 Maximum Subsequence Sum (25 分)【难度: 一般 / 知识点: 最大子序列和】

    https://pintia.cn/problem-sets/994805342720868352/problems/994805514284679168 方法一: 前缀和+枚举 时间复杂度: O(n ...

  9. 【PAT甲级 最长公共子串】1007 Maximum Subsequence Sum (25 分) C++ 全部AC

    题目 读题!读题! 题上让输出最长子串起始位置和终止位置的数字,而不是角标 如果每个数都是负数,则输出0 不要看着测试用例去猜题意,要先把题完整看完了再开始码! 如果自己的测试用例全都通过了,题目的测 ...

最新文章

  1. VS2017 Pro未能找到路径“……\bin\roslyn\csc.exe”的解决方案
  2. JavaScript中的预解析(变量提升)介绍!
  3. android 自定义view实现拖动放大缩小_自定义itemCheckView
  4. 动态改变stage桢数
  5. 【转载】如何制作python安装模块(setup.py)
  6. 《上古天真论》第六讲文字版
  7. 软件工程实践 Blog5
  8. 地下城php补丁怎么用,dnf补丁怎么用,教你如何学会使用补丁
  9. 【小刘带你玩儿前端】什么是跨域以及如何解决?小刘带你轻松拿彻底解决~
  10. 在“动物杂交:新视野”中快速赚钱的9种方法
  11. 使用PlatformIO IDE开发Arduino如何安装和调用外部库文件【基于Visual Studio Code平台】
  12. 详解Unity中的粒子系统Particle System (四)
  13. 【案例教程】基于RWEQ模型的土壤风蚀模数估算及其变化归因分析实践技术
  14. Intel(Altera)FPGA的SOF转JIC文件和下载详细教程
  15. Tek(泰克)示波器如何导出波形数据到U盘
  16. cad无法启动此程序 因为计算机中丢失,Win10无法启动CAD提示计算机中丢失ac1st16怎么办?...
  17. python3 diff函数案例
  18. 【CSS】css 获取从第n个元素开始,之后的所有元素 :nth-of-type(n)与:nth-child(n)
  19. java咖啡机提示除钙,请注意:租赁咖啡机的14种错误用法!-人人租机
  20. 静态电影网站模板A(html+css+js)

热门文章

  1. 前端学习(46):页面导入样式时,使用link和@import有什么区别?
  2. 第六十六期:软件架构之道的一次感悟
  3. 第五十二期:甲骨文遭遇“中年危机”:继阿里后,再被亚马逊永久抛弃
  4. java学习(58):私有内部类后访问
  5. 如何用脚本可靠关闭一个linux服务或进程
  6. STM32的I2C主从机通信
  7. pcap python 生成_python+pcap+dpkt 抓包小实例
  8. linux 查当前pid_杀死僵尸进程,你需要这些神奇高效的Linux命令行
  9. mysql安装innodb插件
  10. POJ1459 Power Network —— 最大流