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

     输入一个长度为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.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值