KY141 最大连续子序列

KY141 最大连续子序列 题解

题目地址
题目描述

 给定K个整数的序列{ N1, N2, ..., NK },
 其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },
 其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,
 例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 
 13 },最大和为20。
 现在增加一个要求,即还需要输出该子序列的第一个和最后一个元素。

输入

测试输入包含若干测试用例,每个测试用例占2行,
第1行给出正整数K( K< 10000 ),
第2行给出K个整数,中间用空格分隔。
当K为0时,输入结束,该用例不被处理。

输出

对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元素,
中间用空格分隔。如果最大连续子序列不唯一,则输出序号
i和j最小的那个(如输入样例的第2、3组)。
若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。

样例

6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0

补充
根据样例看,输出还有一个要求就是如果序列中的最大数为0,那么输出三个0

思路
正常求最大连续子序列,同时设置三个指针,分别指向最大连续子序列的开始位置、结束位置,和当前连续子序列的开始位置,这是因为并不清楚当前连续子序列是否比之前的大,如果大,就要更新最大连续子序列的开始位置

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>

using namespace std;

const int MAXN=10000;

int arr[MAXN];
int dp[MAXN];

int main(){
    int k;
    while (cin>>k)
    {
        if(k==0){
            break;
        }
        vector<int> list;
        for(int i=0;i<k;i++){
            int t;
            cin>>t;
            list.push_back(t);
        }

        //用一个暂时vector判断是否全为负数
        vector<int> list_temp=list;
        //给暂时序列排序
        sort(list_temp.begin(),list_temp.end());
        if(list_temp[list_temp.size()-1]<0){
            //整个序列全为负数
            //认为其和为0
            cout<<0<<" "<<list[0]<<" "<<list[list.size()-1]<<endl;
        }else if(list_temp[list_temp.size()-1]==0){
            //如果最大的元素是0
            cout<<0<<" "<<0<<" "<<0<<endl;
        }else{
            //否则,在正常情况下
            int maximum=0; //最大连续子序列的和
            int max_start=0; //最大连续子序列的开始位置
            int max_end=0; //最大连续子序列的结束位置
            int current_strat=0;//当前子序列开始的位置

            for(int i=0;i<k;i++){
                if(i==0){
                    dp[i]=list[i];
                }else{
                    if((dp[i-1]+list[i])<list[i]){
                        current_strat=i; //更新新的子序列开始的位置
                    }
                    dp[i]=max(dp[i-1]+list[i],list[i]);
                }
                if(maximum<dp[i]){
                    //当前的子序列的和更大
                    //更新最大子序列的开始位置
                    max_start=current_strat;
                    max_end=i;
                }
                //否则的话,不更新
                maximum=max(maximum,dp[i]);
            }
            cout<<maximum<<" "<<list[max_start]<<" "<<list[max_end]<<endl;

        }
    }
   
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光头强12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值