【最大子序列和】解题报告

     输入一个长度为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 
//using std::cout;
//using std::cin;
#include 
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;im)l++;
		if (sum[i]-sum[que[l+1]]>max)
			max = sum[i]-sum[que[l+1]];
		if (max=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.

你可能感兴趣的:(NOIP)