最大子序列的和 (sequence)
输入一个长度为n的整数序列(A1,A2,……,An),从中找出一段长度不超
过m 的连续的子序列,使得这个序列的和最大。
例如:序列 1,-3,5, 1,-2,3
当M=2 或3 时,S=5+1=6,当M=4 时,S=5+1-2+3=7
输入文件:(input.txt)
第一行为两个数n 和m ,第二行为不超过integer 的n 个整数,两个数之
间用一个空格隔开。
输出文件: (output.txt)
最大的子序列和。
样例输入:
6 3
1 -3 5 1 -2 3
样例输出:
6
数据范围:
50%的数据N,M<=1000
100%的数据N,M<=20000
====================================
===========================
朴素n^2,由于数据较若可以全过
-------------------------------------------
var {50分算法}
n,m:longint;
a:array[1..20000]of longint;
sum:array[0..20000]of longint;
procedure init;
begin
assign(input,'sequence.in');
assign(output,'sequence.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
procedure main;
var
i,j:longint;
ans:longint;
begin
readln(n,m);
sum[0]:=0;
for i:=1 to n do
begin
read(a[i]);
sum[i]:=sum[i-1]+a[i];
end;
ans:=-maxlongint;
for i:=1 to n do
for j:=i-1 downto max(0,i-m) do
begin
if sum[i]-sum[j]>ans then ans:=sum[i]-sum[j];
end;
writeln(ans);
end;
begin
init;
main;
terminate;
end.
---------------------------------------------------------------
单调队列优化。
期望得分100分
----------------------------------------
var
n,m:longint;
a:array[0..200000]of longint;
q:array[0..200000]of longint;
sum:array[0..200000]of longint;
procedure init;
begin
assign(input,'sequence.in');
assign(output,'sequence.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
procedure main;
var
i,j:longint;
ans:longint;
l,r:longint;
begin
readln(n,m);
sum[0]:=0;
for i:=1 to n do
begin
read(a[i]);
sum[i]:=sum[i-1]+a[i];
end;
l:=0; r:=0;
fillchar(q,sizeof(q),0);
ans:=-maxlongint;
for i:=1 to n do
begin
while (l<=r)and(i-q[l]>m) do inc(l); {维护区间的长度<=m}
while (l<=r)and(sum[q[r]]>=sum[i]) do dec(r); {从队尾开始剔除不可能点}
inc(r);
q[r]:=i;
if l=r then {队列中只有一个元素的情况特殊考虑}
begin
if sum[i]-sum[i-1]>ans then ans:=sum[i]-sum[i-1];
end
else
if sum[i]-sum[q[l]]>ans then ans:=sum[i]-sum[q[l]];
end;
writeln(ans);
end;
begin
init;
main;
terminate;
end.