题目描述
牛A最喜欢打水漂(当然不是指用他的钱)了!他的力气灰常大,所以他的石子可以打到水中的任何一条鱼(水是很浅的)。但是力气大不代表技术好,牛A的石子在水面上只能蹦两下,就被和谐了。。。不过,因为力气大嘛,牛A可以控制石子蹦的距离。
今天他又来打了,现在的河面上有N条小鱼排成了一列等着牛A(好傻的鱼)。这些鱼的身上绑定了钻石和石头,它们都有自己的价格,其中钻石的价格一定是正整数,石头的价格一定是负整数(你会花钱买石头吗)。牛A的石头有魔法,被石头第一次落水到第二次落水划过的弧线笼罩下的鱼的钻石或石头会自动跑到牛A那里。
牛A想知道,他要如何控制石子蹦的距离,以使钻石和石头的价值和最大。
输入格式:
第一行一个整数N
第二行N个整数表示每条鱼身上的钻石或石头的价格
输出格式:
第一行两个整数表示石头最优的两个落点
第二行一个整数表示最大的价值和
当然,如果每条鱼身上都是石头,牛A就会离开,此时两个落点、最大价值和均为0
说明
0< N <10001
价格的绝对值<501
题解
闲得蛋疼来刷比赛,找来找去似乎只有洛谷有了,看到很水啊就直接上了
顺便说一下,用的sublime+命令行gdb+g++,爽到爆毕竟第一次用文字界面不熟悉也不习惯(语义重复?)
言归正传,赤裸裸的求区间最大和,附带求位置,用一个队列记录经过的数字,对于小于0的和的区间舍弃,每次用当前队列总和更新ans
代码
#include <stdio.h>
#include <queue>
using namespace std;
queue<int>q;
int a[10002];
int n,sum=0,ans=0;
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
int i=0,x=1,y=0;
int l,r;
while (++i<=n)
{
q.push(a[i]);
sum+=a[i];
y++;
if (sum<0)
{
while (q.size())
{
sum-=q.front();
q.pop();
x++;
}
}
if (sum>ans)
{
ans=sum;
l=x;
r=y;
}
}
printf("%d %d\n",l,r);
printf("%d\n",ans);
return 0;
}