zoukankan      html  css  js  c++  java
  • PAT 甲级测试题目 -- 1007 Maximum Subsequence Sum

    题目链接

    题目描述

      给一组序列的个数 N(N < 10000)以及序列中的数,要求计算出该序列中连续子序列和值最大的子序列,输出这个最大值以及子序列的第一个元素和最后一个元素,若序列中的值均为负数,则子序列和值最大为0,输出序列的第一个元素和最后一个元素。

    分析

      由于题目中给出的个数在 10000 左右,因此使用数组存储子序列不是一个好办法。
    由于题目中表明是计算连续的子序列,因此可以这样推理结果:
      若有序列{ a1, a2, a3, a4, a5, a6},且 a2 至 a6 的子序列和为正数,a1 为负数,那么子序列 { a1, a2, a3, a4, a5, a6 } 一定不是该序列的最大值,因此可以舍弃元素 a1。也由此可以推出,若有子序列1,子序列2以及子序列3,且子序列1,子序列2之和为负数,子序列3之和为正数,那么子序列3的和可能为该序列的最大子序列和。由此可以推出思路:

    设置最大值 maxium 为 0,用 currentAdd 变量记录当前加和的值,
    若 currentAdd 大于 maxium,则将 currentAdd 赋值给 maxium,若 currentAdd 为负数,则将其置于 0。这样就能狗找出子序列的最大和。
    

    因此,我们可以避免使用数组存储数据,而是动态处理输入数据,解决了空间复杂度问题。

      除了找出子序列的最大和值之外,题目中还要求找出输出这个子序列的第一个元素和最后一个元素。因此需要一个标记记录子序列的首尾元素。因为子序列的首元素由 currentAdd 决定,因此它随着该变量的变化而变化,尾元素则随着 maxium 被找到而变化,记录当前的输入的元素。

      由于在序列中找到的正数不一定是最大值,所以我们需要额外的变量记录首尾元素,直到子序列的和比之前记录的最大值还要大的时候,才将额外的变量值赋值给需要输出的首尾元素值。

      由于题目中有可能出现序列中所有元素为负数的情况,且这种情况下需要输出序列的首尾元素。因此我们需要额外的变量记录序列的第一个元素和最后一个元素。

      题目中也透露了一个不明显的信息,就是序列中子序列最大值为 0 的情况,因此也应当将其考虑进去,所以设置 maxium 为 -1,区别序列元素均为负数的情况,以及序列中子序列最大和值为 0 的情况。

    实现

    #include<iostream>
    using namespace std;
    int main() {
    	int numbers;
    	// 最大值记为 -1 用于处理子序列和最大值为 0 的情况
    	int maxium = -1;
    	int currentAdd = 0;
    	int leftIndex, rightIndex;
    	int leftFlag, rightFlag;
    	int first, last;
    	int currentNum;
    	
    	first = last = leftFlag = rightFlag = leftIndex = rightIndex = 0;
    	// 接收输入的序列长度
    	cin >> numbers;
    	for (int i = 0; i < numbers; i++) {		
    		// 接收序列数字
    		cin >> currentNum;
    		// 记录序列的开头
    		if (first == 0)
    			first = currentNum;
    		// 记录序列的结尾
    		last = currentNum;
    		// 记录当前的子序列和
    		currentAdd += currentNum;
    		// 记录子序列的开头
    		if (leftFlag == 0)
    			leftFlag = currentNum;
    		// 若当前子序列和为负数,则置于0
    		if (currentAdd < 0) {
    			leftFlag = currentAdd = 0;
    			continue;
    		}
    		// 若当前子序列和比最大值大,则用最大值接收该子序列和,并记录子序列的开头与结尾
    		if (currentAdd > maxium) {
    			rightIndex = rightFlag = currentNum;
    			leftIndex = leftFlag;
    			maxium = currentAdd;
    		}
    
    	}
    	// 若子序列的和为负数,则将子序列开头记为序列开头,子序列结尾记为序列结尾,最大值记为 0 
    	if (maxium == -1) {
    		leftIndex = first;
    		rightIndex = last;
    		maxium = 0;
    	}
    	
    	cout << maxium << " " << leftIndex << " " << rightIndex;
    	return 0;
    }
    

    希望对你有所帮助!

  • 相关阅读:
    HDU5730 Shell Necklace
    BZOJ4883 [Lydsy2017年5月月赛]棋盘上的守卫
    Spring boot 配置文件
    org.joda.time.DateTime 日期操作
    Elasticsearch + Springboot 启动报错 java.net.ConnectException: Connection refused
    centos7 在docker下安装es Elasticsearch
    centos 7 。 docker 安装rabbitmq 以及集权搭建
    linux 安装mysql5.7.25
    安装rabbtimq CentOS 7
    docker + spring boot 打包 部署。
  • 原文地址:https://www.cnblogs.com/Breathmint/p/10275935.html
Copyright © 2011-2022 走看看