题目描述
安柏一天正在蒙德城外探险,突然发现了一个宝箱,但是只有点燃前面的 n 个火炬才能点亮宝箱下面的魔纹获得宝箱。n个火炬的编号为从 1 到 n 按顺序排列,而这 n 个火炬的能量分别为 ai(1<=i<=n),现在询问 m 次,每次告诉你一个数字 x,安柏能点燃编号从 L 到 R的所有火炬(其中 R-L+1 >= x),请你求出她所能点燃的最大能量。(对于 m 次点燃,每次点燃前所有火炬会全部熄灭)
输入
第一行两个数,表示 n 和 m 。
之后 n 个数,表示 n 个火炬的能量。
之后 m 行每行一个数 x,表示询问的数字。
输出
输出 m 行,为安柏每次所能点燃的最大能量
输入样例
4 4
1 2 3 4
1
2
3
4
输出样例
10
10
10
10
数据范围
1<=x<=n<=104,0<=m<=105,|ai|<=104
Hint
选一个区间长度>=x的区间,求区间最大和
思路分析
由于m范围比n大,我们可以先把每一个x对应的≥x的子区间最大和求出来,对m个x直接输出答案。
当x = n时,区间最大和即为区间全部元素的和。
当x = i时,遍历每一个长度为i的子区间,与x = i+1对应的值和比较,取最大值。
直到x = 1为止。
AC代码
#include<stdio.h>
int max_x[10010],num[10010];
int main()
{
int n,m,x,i,j,MAX=-100000005;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
for(i=n;i>0;i--)
{
int max,premax=0;
for(j=1;j<=i;j++)
premax+=num[j];
max=premax;
for(j=1;j<=n-i;j++)
{
premax=premax-num[j]+num[j+i];
if(premax>max) max=premax;
}
if(max>MAX) MAX=max;
max_x[i]=MAX;
}
for(i=0;i<m;i++)
{
scanf("%d",&x);
printf("%d\n",max_x[x]);
}
}