题目描述
给一个序列
a
1
,
a
2
,
a
3
.
.
.
.
.
.
a
n
a_1,a_2,a_3......a_n
a1,a2,a3......an
每次给你一个
l
l
l一个
r
r
r,(
l
l
l和
r
r
r被使用后不能继续使用,即使将之前用过的l作为新的
r
r
r也不可以)
你需要做的是按一定的顺序取
l
,
r
l,r
l,r使下列式子的总和最大
∣
∑
j
=
l
+
1
r
a
j
∣
−
C
|\sum_{j=l+1}^ra_j|-C
∣j=l+1∑raj∣−C
给出的数据有数列大小
n
n
n和
a
1
,
a
2
.
.
.
.
a
n
a_1,a_2....a_n
a1,a2....an和
C
C
C
题解:
绝对值里面的东西就是前缀和,麻烦的是怎么取最大值???
每次选最大前缀和去减最小的前缀和!!!!这就是解题源头了,不过要记得加一个sum=0的项,因为
l
l
l是可以为
0
0
0的,为保证可以取到一个完整的前缀和
详细请看代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5;
int n,m,c;
int a[maxn];
int sum[maxn];
int main()
{
while(~scanf("%d%d%d",&n,&m,&c))
{
for(int i=1;i<=n;i++)scanf("%d",a+i);
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
sum[++n]=0;
sort(sum+1,sum+1+n);
ll ans=0;
ll pans=0;
for(int i=1,j=n;i<=m;i++,j--)
{
ans=ans+abs(sum[j]-sum[i])-c;
pans=max(pans,ans);
}
printf("%lld\n",pans);
}
return 0;
}