浙大数据结构网课第一周入门

news2024/9/25 8:30:33

题目详情

Given a sequence of K integers { N1​, N2​, ..., NK​ }. A continuous subsequence is defined to be { Ni​, Ni+1​, ..., Nj​ } 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

代码长度限制

16 KB

时间限制

200 ms

内存限制

64 MB

简单翻译:

对于给定数组,不仅要找到最大子序和,还要找到最大子序和对应的开头与结尾的元素,其中如果数组全是负数就返回0与锁哥数组的开头与结尾元素

第一次写错误:

(1)要求的是最大子序和对应的开头与结尾的元素,一开始就返回的是下标

(2)没有看清如果数组全是负数就返回0与锁哥数组的开头与结尾元素

(3)没有考虑好如果数组全是负数与数组里只有负数和0的情况

代码实现:

#include <iostream>
#include <limits.h>
using namespace std;
int main(void) {
    int K;
    cin >> K;
    int a[K];
    for(int i = 0; i < K; i++) {
        cin >> a[i];
    }
    int maxSum = INT_MIN; 
    int sum = 0;
    int end = 0, maxEnd = 0;
    int start = 0, maxStart = 0;
    for(int i = 0; i < K; i++) {
        sum += a[i];
        end = i;
        if(sum < 0) {
            sum = 0;
            end = start = i + 1;
        }
        else {
            if(maxSum < sum) {
                maxSum = sum;
                maxEnd = end;
                maxStart = start;
            }
        }
    }
    if(maxSum == INT_MIN) {    //如果maxSum还是INT_MIN,说明数组里全是负数
        cout << 0 << ' ';
        cout << a[0] << ' ';
        cout << a[K - 1] << endl;
    }
    else {
        cout << maxSum << ' ';
        cout << a[maxStart] << ' ';
        cout<< a[maxEnd] << endl;        
    }
}

题目详情

给定K个整数组成的序列{ N1​, N2​, ..., NK​ },“连续子列”被定义为{ Ni​, Ni+1​, ..., Nj​ },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:

  • 数据1:与样例等价,测试基本正确性;
  • 数据2:102个随机整数;
  • 数据3:103个随机整数;
  • 数据4:104个随机整数;
  • 数据5:105个随机整数;

输入格式:

输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。

输出格式:

在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。

输入样例:

6
-2 11 -4 13 -5 -2

输出样例:

20

思路一:贪心

时间复杂度O(N)

代码实现:

#include <iostream>
using namespace std;
int main(void) {
    int K;
    cin >> K;
   int num[K];
    for(int i = 0; i < K; i++) {
        cin >> num[i];
    }
    int sum = 0;
    int maxSum = 0;
    for(int i = 0; i < K; i++) {
        sum += num[i];
        if(sum < 0) {
            sum = 0;
        }
        else {
            if(sum > maxSum) {
                maxSum = sum;
            }
        }
    }
    cout << maxSum;
    return 0;
}

 

 思路二:递归分治

主要思路:

1. 将序列从中间分为左右两个序列

2. 递归求得两子列的最大和sumLeft与sumRight

3.从中分点向左右扫描找到跨过分界线的最大子列和sumMiddle

4.取最大值

实际操作时递归三部曲:

1.参数与返回值:

参数:num数组,返回当前子列和最大值

2.终止条件:

左右端点重合

3.单层递归逻辑:

单纯左侧与单纯右侧简单,难的是跨中间点

跨中间点其实也用到了贪心的想法,即分成两部分,分别找左[left, middle]与右[middle + 1, right]的最大值,然后加起来就是跨中间点最大值

代码实现 

#include <iostream>
#include <vector>
using namespace std;
int layer = 0;
int Max3(int A, int B, int C) { //这个函数是用来比较左中右里最大值
    return A > B ? A > C ? A : C : B > C ? B : C;
    /* 
        A > B ? A > C ? A : C :
        这一部分首先判断 A 是否大于 B,如果是,则继续判断 A 是否大于 C,如果是,则返回 A,否则返回 C。

        如果 A 不大于 B,则执行下一个部分:

        B > C ? B : C
        这一部分首先判断 B 是否大于 C,如果是,则返回 B,否则返回 C。
     */
}
int findMaxMiddleSum(vector<int> &num, int left, int right, int middle) {   //这个函数是用来找“中”(跨越中间分界点)的最大值
    int leftSideSum = 0, leftSideMaxSum = 0;
    for(int i = middle; i >= left; i--) {
        leftSideSum += num[i];
        if(leftSideSum > leftSideMaxSum) {
            leftSideMaxSum = leftSideSum;
        }
    }
    
    int rightSideSum = 0, rightSideMaxSum = 0;
    for(int i = middle + 1; i <= right; i++) {
        rightSideSum += num[i];
        if(rightSideSum > rightSideMaxSum) {
            rightSideMaxSum = rightSideSum;
        }
    }
    return leftSideMaxSum + rightSideMaxSum;
}
int recursion(vector<int> &num, int left, int right) {
    //递归终止条件
//    cout << "left = " << left << endl;
//    cout << "right = " << right << endl;
//    cout << "layer = " << ++layer << endl;
    if(left == right) {
        if(num[left] > 0) {
            return num[left];
        }
        else return 0;
    }
    //单层递归逻辑
    int middle = (left + right) / 2;
//    cout << "middle = " << middle << endl;
    int leftSum = recursion(num, left, middle);
    int rightSum = recursion(num, middle + 1, right);
    int middleSum = findMaxMiddleSum(num, left, right, middle);
    return Max3(leftSum, rightSum, middleSum);
}
int main(void) {
    int K;
    cin >> K;
    vector<int> num(K, 0);
    for(int i = 0; i < K; i++) {
        cin >> num[i];
    }
//    for(int i = 0; i < K; i++) {
//        cout << num[i] << " ";
//    }
//    cout << endl;
//    cout << "-------------------------" << endl;
    int maxSum = recursion(num, 0, K - 1);
    cout << maxSum;
    return 0;
}

时间复杂度分析:

N代表长度

N = 2 ^ k

k = logN

T(N) = N * O(1) + c * O(NlogN)

空间复杂度 

递归的空间复杂度=递归深度*每次递归的空间复杂度。每次递归边界变为一半,最后结束递归时N/2^k=1,递归深度k=log2 N,S(N)=O(NlogN)

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

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

相关文章

RBF-UKF径向基神经网络结合无迹卡尔曼滤波估计锂离子电池SOC(附MATLAB代码)RBF神经网络训练部分

1.清空变量 close all clear,clc 2.导入数据用以RBF神经网络训练&#xff0c;一共14组&#xff0c;训练数据P&#xff08;第一列为电压值&#xff0c;第二列为SOC值&#xff0c;第三列为电流值。&#xff09;&#xff0c;并将所有数据存储在变量PP中&#xff0c;所有电压数据…

蓝桥杯:优秀的拆分

蓝桥杯&#xff1a;优秀的拆分https://www.lanqiao.cn/problems/801/learning/ 目录 题目描述 输入描述 输出描述 输入输出样例 输入 输出 输入 输出 题目分析&#xff08;位运算&#xff09; AC代码&#xff08;Java) 题目描述 一般来说&#xff0c;一个正整数可以拆…

【】:addService 和 getService

一次完整的 Binder IPC 通信过程通常是这样&#xff1a; 首先 Binder 驱动在内核空间创建一个数据接收缓存区&#xff1b; 接着在内核空间开辟一块内核缓存区&#xff0c;建立内核缓存区和内核中数据接收缓存区之间的映射关系&#xff0c;以及内核中数据接收缓存区和接收进程用…

无线传感器网络硬件设计简介

无线传感器网络硬件设计简介 无线传感器网络因其巨大的应用前景越来越受到学术界和工业界的广泛关注。本文介绍了无线传感器网络节点的体系结构&#xff0c;分析比较了国内外当前典型的硬件平台&#xff0c;重点讨论了目前无线传感器网络节点常用的处理器、射频芯片、电源和传…

孩子为什么不能玩抖音精彩回答,共勉

2 可是&#xff0c;为什么我的同学、哥哥姐姐…… 反正身边好多人都在玩&#xff1f; 我不知道你父母有没有告诉你这个道理&#xff1a; 你把时间花在哪儿&#xff0c; 你就会成为什么样的人。 他们爱玩&#xff0c;是因为两个字&#xff1a; 空虚。 想象一下&#xff…

02、Cadence使用记录之创建元器件---原理图和封装(OrCAD Capture CIS)

02、Cadence使用记录之创建元器件—器件原理图符号和封装&#xff08;OrCAD Capture CIS&#xff09; 参考的教程是B站的视频&#xff1a;allegro软件入门视频教程全集100讲 前置教程&#xff1a; ## 01、Cadence使用记录之新建工程与基础操作&#xff08;原理图绘制&#xf…

新闻文本分类任务:使用Transformer实现

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

13.网络爬虫—多进程详讲(实战演示)

网络爬虫—多进程详讲 一进程的概念二创建多进程三进程池四线程池五多进程和多线程的区别六实战演示北京新发地线程池实战 前言&#xff1a; &#x1f3d8;️&#x1f3d8;️个人简介&#xff1a;以山河作礼。 &#x1f396;️&#x1f396;️:Python领域新星创作者&#xff0c…

Spark SQL实战(07)-Data Sources

1 概述 Spark SQL通过DataFrame接口支持对多种数据源进行操作。 DataFrame可使用关系型变换进行操作&#xff0c;也可用于创建临时视图。将DataFrame注册为临时视图可以让你对其数据运行SQL查询。 本节介绍使用Spark数据源加载和保存数据的一般方法&#xff0c;并进一步介绍…

node安装

一、下载nodejs的安装包&#xff1a; 下载地址&#xff1a;https://nodejs.org/zh-cn/download 根据自己电脑系统及位数选择&#xff0c;一般都选择windows64位.msi格式安装包 二、改变nodejs的下载依赖包路径 安装完nodejs后&#xff0c;也同时安装了npm&#xff0c; npm是…

半监督语义分割_paper reading part1

Assignment 要解决的问题思路方法结果自己的想法 01 A Survey on Semi-Supervised Semantic Segmentation University of Granada, 18071, Granada, Spain 2023.02出版 problem to solve ss先前的&#xff08;19年&#xff09;不适用先前的调研包含弱监督&#xff0c;ss不…

Docker Desktop使用PostgreSql配合PGAdmin的使用

在看此教程之前&#xff0c;请先下载安装Docker Desktop 安装成功可以查看版本 然后拉取postgresql的镜像&#xff1a;docker pull postgres:14.2 版本可以网上找一个版本&#xff0c;我的不是最新的 发现会报一个问题 no matching manifest for windows/amd64 10.0.19045 i…

小心,丢失的消息!RocketMQ投递策略帮你解决问题!博学谷狂野架构师

RocketMQ消息投递策略 作者: 博学谷狂野架构师GitHub&#xff1a;GitHub地址 &#xff08;有我精心准备的130本电子书PDF&#xff09;只分享干货、不吹水&#xff0c;让我们一起加油&#xff01;&#x1f604; 前言 RocketMQ的消息投递分分为两种&#xff1a;一种是生产者往MQ …

java中级面试题

1.假如有两个线程共同操作数据库&#xff0c;以乐观锁的角度考虑&#xff0c;怎么确保不会发生并发问题&#xff1f; PS&#xff1a;考点是CAS&#xff0c;比较并替换。CAS中有三个值&#xff0c;内存中的值&#xff0c;新值&#xff0c;旧值。 假如内存中的值是2000&#xf…

[C++]string类的模拟实现和相关函数的详解

目录string总体架构具体实现默认成员函数构造函数构造拷贝函数析构函数赋值重载[]相关操作函数c_str() && size()reserve() && resize()push_back() && append()find()inserterase() && clear其余操作符重载< 、 <、 >、 >、 !<…

【系统集成项目管理工程师】项目整体管理

&#x1f4a5;十大知识领域&#xff1a;项目整体管理 项目整体管理包括以下 6 个过程: 制定项目章程定项目管理计划指导与管理项目工作监控项目工作实施整体变更控制结束项目或阶段过程 一、制定项目章程 制定项目章程。编写一份正式文件的过程&#xff0c;这份文件就是项目章程…

某程序员哀叹:月薪四五万,却每天极度焦虑痛苦,已有生理性不适,又不敢裸辞,怎么办?

高薪能买来快乐吗&#xff1f; 来看看这位程序员的哀叹&#xff1a; 实在是扛不住了&#xff0c;每天都在极度焦虑和痛苦中度过&#xff0c;早上起来要挣扎着做心理建设去上班&#xff0c;已经产生生理性的头晕恶心食欲不振。有工作本身的原因&#xff0c;更多是自己心态的问…

OpenCV+FFmpeg 实现人脸检测Rtmp直播推流(Python快速实现)

实现效果 windows平台笔记本摄像头视频采集、人脸识别&#xff0c;识别后将视频推流到RTMP流媒体服务器&#xff0c;在任意客户端可以进行RTMP拉流播放。 效果如图&#xff1a; 使用VLC播放器进行拉流。 准备工作 需要先安装OpenCV的python包以及FFmpeg。 对于ffmpeg有两…

Java——删除链表中重复的节点

题目链接 牛客在线oj题——删除链表中重复的节点 题目描述 在一个排序的链表中&#xff0c;存在重复的结点&#xff0c;请删除该链表中重复的结点&#xff0c;重复的结点不保留&#xff0c;返回链表头指针。 例如&#xff0c;链表 1->2->3->3->4->4->5 处…

【Vue】学习笔记-数据代理

数据代理 Object.defineproperty方法 <script type"text/javascript">let number18let person{name:张三,sex:男,}//age属性 不参与遍历Object.defineProperty(person,age,{//value:18,//enumerable:true, //控制属性是否可以枚举&#xff0c;默认值是false//…