1007. Maximum Subsequence Sum (25)


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;  
}  

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验项目 3-4:一元多项式的乘法与加法运算

代码如下&#xff1a; /*************************************************************************> File Name: AddPoly.c> Author: YueBo> Mail: yuebowhu163.com> Created Time: 2016年12月17日 星期六 13时00分35秒***************************************…

树的同构

输入样例1&#xff08;对应图1&#xff09;&#xff1a;8A 1 2B 3 4C 5 -D - -E 6 -G 7 -F - -H - -8G - 4B 7 6F - -A 5 1H - -C 0 -D - -E 2 -输出样例1:Yes输入样例2&#xff08;对应图2&#xff09;&#xff1a;8B 5 7F - -A 0 3C 6 -H - -D - -G 4 -E 1 -8D 6 -B 5 -E - -…

.Net 中接口应用的知识点(排序)

接口 接口可以看作是多态的一种。它打破了里氏替换原则。即不是共同的生物&#xff0c;比如动物&#xff08;狗&#xff09;和人&#xff08;老师&#xff09;&#xff0c;这两个类 却都有吃这种方法。但是继承里不能把老师和狗归为一个类。所以这时用接口来解决这种问题。 语法…

leetcode 121

leetcode 121 dp? my answer class Solution { public:int maxProfit(vector<int>& prices) {int bdprices[0],sd0;int max_num0;for(int i1;i!prices.size();i){sdprices[i];if(sd<bd) bdsd;else if(sd-bd>max_num)max_numsd-bd;}return max_num;} };END

.net中的硬盘操作(针对Windows )

1&#xff0c;文件与文件夹的读取&#xff08;针对Windows &#xff09; 这是程序员的基本功。 做这种操作首先要引入一个命名空间 using System.IO I input 输入 O output 输出File.Create("C:\1.txt"); file是个静态类&#xff0c;里面有很多方法&#xff0c;多是…

优秀设计师是如何炼成的,看搜狐如何做设计

《设计之下》终于上市了&#xff0c;回忆一下整个成书的过程&#xff0c;不得不佩服作者&#xff0c;从最开始的干净利落&#xff0c;到最终的细节的调整&#xff0c;作为编辑我对他们的认识逐渐加深&#xff0c;也慢慢了解了优秀设计师是如何炼成的。 这本书源于2012年12月份的…

1092. To Buy or Not to Buy (20)

1092. To Buy or Not to Buy (20) 时间限制100 ms内存限制65536 kB代码长度限制16000 B判题程序Standard作者CHEN, YueEva would like to make a string of beads with her favorite colors so she went to a small shop to buy some beads. There were many colorful strings …

.net动态控件的使用(listview ,treeview,tabControl)

对于控件中显示的数据可能是不固定的。如果固定&#xff0c;数据发生了变化&#xff0c;又要重新设计&#xff0c;这样浪费成本&#xff0c;资源。 所以有用代码操作控件&#xff0c;自由度&#xff0c;可控度高。 1&#xff0c;树控件 //把 tv 作为全局变量 &#xff0c; 这是…

泡茶看数据结构-临时(对象设计技术)

一.开场白 第二次《DATA STRUCTURES AND PROBLEM SOVLING WITH C》英文授课&#xff0c;让我产生英文写文章的念头。但是&#xff0c;慢慢开始参合英文吧。一下子写的话&#xff0c;怕写出来博客园首页都不敢收录了。^_^&#xff01;今天&#xff0c;从课堂和自己下午看总结下,…

前端学习(1002):简洁版滑动下拉菜单问题解决

快速滑动 不停切换 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><scrip…

js bom and dom

以下的代码只是一些小的例子。我画了一张图来总结js大的结构 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><script>//Point 1 delayer and timer (BOM browser Object Model)var delayer;var tim…

leetcode 383 赎金信 C++

自己想的&#xff0c;一个思路两个解法&#xff0c;从字符串中的第一个唯一字符的思路搬过来的 one class Solution { public:bool canConstruct(string ransomNote, string magazine) {int table2[26]{0};for(int i0;i!magazine.length();i){table2[magazine[i]-a];}for(int …

Win32下 Qt与Lua交互使用(二):在Lua脚本中使用Qt类

话接上篇。成功配置好QtLuatoLua后&#xff0c;我们可以实现在Lua脚本中使用各个Qt的类。直接看代码吧。 #include "include/lua.hpp" #include <QWidget> #include <QApplication> #include <QFile> #include <QDebug>static int tolua_new…

1099. Build A Binary Search Tree (30)

1099. Build A Binary Search Tree (30) 时间限制100 ms内存限制65536 kB代码长度限制16000 B判题程序Standard作者CHEN, YueA Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains o…

mysql列属性auto(mysql笔记四)

常见的的是一个字段不为null存在默认值 没值得时候才去找默认值&#xff0c;可以插入一个null到 可以为null的行里 主键&#xff1a;可以唯一标识某条记录的字段或者字段的集合 主键设置 主键不可为null,声明时自动设置为not null 字段上设置 字段名 primary key定义完字段后 …

详解html结构之间的各个关系,层级关系(以列表为例)

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>层级关系查找元素</title></head><body><div id "div">hello<ul id ""><li>li1</li><li>li2</…