输入一个长度为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
这是做过很多次的题目了,单调队列的练习。
不过我这个单调队列不标准。只适用于无下界有上界的范围。
//#include <iostream>
//using std::cout;
//using std::cin;
#include <cstdio>
const long oo = 0x7fff0000;
long n;long m;
long sum[2000002];
long num[2000002];
long max = -oo;
long que[20000002];
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%ld%ld",&n,&m);
long l = 0;long r = 0;
for (long i=1;i<n+1;i++)
{
scanf("%ld",num+i);
sum[i]=sum[i-1]+num[i];
}
for (long i=1;i<n+1;i++)
{
while (l<r&&i-que[l+1]+1>m)l++;
if (sum[i]-sum[que[l+1]]>max)
max = sum[i]-sum[que[l+1]];
if (max<sum[i]) max = sum[i];
while (l<r&&sum[que[r]]>=sum[i])r--;
que[++r] = i;
}
printf("%ld",max);
return 0;
}
较标准的见张凯锋
program bstation;
var
n,i,j,k,x,now,cost,water,max:longint;
w,l,p:array[1..100000]of longint;
sum:array[1..100000]of longint;
v,ans:array[1..15000]of boolean;
procedure reading;
begin
assign(input,'bstation.in');reset(input);
assign(output,'bstation.out');rewrite(output);
readln(n);max:=maxlongint;
fillchar(ans,sizeof(ans),false);
for i:=1 to n do readln(w[i],l[i],p[i]);
for i:=1 to n do sum[i]:=sum[i-1]+w[i];
end;
begin
reading;
for i:=1 to n do
begin
fillchar(v,sizeof(v),false);
water:=w[i];
cost:=p[i];
now:=i;
v[i]:=true;
while now<>n do
begin
inc(now);
if water+w[now]<=l[now] then
begin
inc(cost,p[now]);
v[now]:=true;
end;
water:=water+w[now];
end;
if cost<=max then
begin
max:=cost;
ans:=v;
end;
end;
for i:=1 to n do if ans[i] then writeln(i);
close(input);
close(output);
end.