您的位置:首页 > 理论基础 > 数据结构算法

数据结构(陈越) 作业题 第一周

2016-02-16 21:15 423 查看

1-1最大子列和问题20pts

时间限制
10000ms

内存限制
65536kB

代码长度限制
8000B

判题程序
Standard

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

输入格式:

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

输出格式:

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

输入样例:
6
-211-413-5-2

输出样例:
20

此题在姥姥的视频里有讲,一共讲了4种方法,其中最优的是在线算法,此处我不再赘述,直接贴上代码,详情请看姥姥的视频讲解。


#include<iostream>
usingnamespacestd;

intmain()
{
intN;
cin>>N;

intthis_sum=0;
intmax_sum=0;
intelement=0;

for(inti=0;i<N;i++)
{
cin>>element;
this_sum+=element;
if(this_sum>max_sum)
max_sum=this_sum;
if(this_sum<0)
this_sum=0;
}

if(max_sum<0)
cout<<0;
else
cout<<max_sum;

return0;
}


1-2.MaximumSubsequenceSum

时间限制
400ms

内存限制
65536kB

代码长度限制
8000B

判题程序
Standard

作者
CHEN,Yue

GivenasequenceofKintegers{N1,N2,...,NK}.Acontinuoussubsequenceisdefinedtobe{Ni,Ni+1,...,Nj}where1<=i<=j<=K.TheMaximumSubsequenceisthecontinuoussubsequencewhichhasthelargestsumofitselements.Forexample,givensequence{-2,11,-4,13,-5,-2},itsmaximumsubsequenceis{11,-4,13}withthelargestsumbeing20.

Nowyouaresupposedtofindthelargestsum,togetherwiththefirstandthelastnumbersofthemaximumsubsequence.

InputSpecification:

Eachinputfilecontainsonetestcase.Eachcaseoccupiestwolines.ThefirstlinecontainsapositiveintegerK(<=10000).ThesecondlinecontainsKnumbers,separatedbyaspace.

OutputSpecification:

Foreachtestcase,outputinonelinethelargestsum,togetherwiththefirstandthelastnumbersofthemaximumsubsequence.Thenumbersmustbeseparatedbyonespace,buttheremustbenoextraspaceattheendofaline.Incasethatthemaximumsubsequenceisnotunique,outputtheonewiththesmallestindicesiandj(asshownbythesamplecase).IfalltheKnumbersarenegative,thenitsmaximumsumisdefinedtobe0,andyouaresupposedtooutputthefirstandthelastnumbersofthewholesequence.

SampleInput:
10
-101234-5-2337-21

SampleOutput:
1014

这题与上一题类似,只不过多出了一个要求:输出最大子列的首尾元素。此题我的做法是,用两个变量l_temp和r_temp记录当前子列的首尾元素,如果该子列的和比当前记录的最大和要大,则用这两个变量更新最大子列的首尾元素l_max和r_max。如果当前子列的和小于0,则从下一个元素开始重新计算。但是有几个特殊点需要注意:

1.如果输入的元素全为负数,则最大和为0,同时输出首尾的负数。
2.如果输入元素全为负数和0,则最大和为0,但输出应该是000.
比如输入-30-6,输出是000,而不是0-3-6
3.输出的首尾元素应该具有最小下标,比如:
输入37-1011,则应输出11311,而不是111111


#include<iostream>
usingnamespacestd;

intmain()
{
intN;
cin>>N;

intthis_sum=0;
intmax_sum=0;
intl_max=0;
intr_max=0;
intl_temp=0;
intr_temp=0;
boolbegin_again=false;//判断this_sum是否重新开始
boolallnegative=true;//判断数组元素是否全为0

int*element=newint
;
for(inti=0;i<N;i++)
{
cin>>element[i];
}

l_temp=element[0];
r_temp=element[0];
for(inti=0;i<N;i++)
{
this_sum+=element[i];

if(element[i]>=0)
allnegative=false;

if(begin_again)
{
l_temp=element[i];
r_temp=element[i];
begin_again=false;
}
else
{
r_temp=element[i];
}

if(this_sum>max_sum)
{
max_sum=this_sum;
l_max=l_temp;
r_max=r_temp;
}
else
if(this_sum<0)//只能用<0,不能<=0,因为要输出smallestindices,若37-1011,则应输出11311,而不是111111
{
this_sum=0;
begin_again=true;//重新开始
}
}

if(max_sum==0)
if(allnegative)
cout<<0<<''<<element[0]<<''<<element[N-1]<<endl;
else
cout<<0<<''<<0<<''<<0<<endl;
else
cout<<max_sum<<''<<l_max<<''<<r_max<<endl;

return0;
}






                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: