题目链接
题意:给定一个序列,找到一个子序列使花费最大。一个子序列的花费=该区间所有值之和-k*区间长度,空序列的花费为0(所以输出的最小值为0)
思路:贪心问题。看了过的大佬的代码好短啊…然后自己想了好久…又打了一遍并且加了注释(只是自己的想法),不知道对不对,有想错的地方欢迎提出。
#include<bits/stdc++.h>
using namespace std;
long long a[300005];
int main()
{
long long n,m,k;
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=1; i<=n; i++)
scanf("%lld",&a[i]);
long long ans=0;
for(int i=0; i<m; i++)//表示:长度对m取余为i的区间
{
//接下来考虑的所有区间 都是长度对m取余为i的区间。
long long now=0,minn=0;//now表示当前的区间花费,minn表示最小的区间花费
for(int j=1; j<=n; j++)
{
now+=a[j];//更新当前值
ans=max(ans,now-k-minn);
//当j%m==i时,now-k相当于当前值,(now-k)-minn表示:最小值区间之后的 到j为止的 区间花费
//当j%m!=i时,这个操作在其他循环中也会进行,这里不用考虑,这里只考虑长度对m取余为i的区间
if(j%m==i)
now-=k;//区间长度每增加m就减去1个k
minn=min(minn,now);//若当前值小于当前最小值,使当前最小值等于当前值。
}
}
printf("%lld\n",ans);
}