CodeForces 1197D Yet Another Subarray Problem

Time limit 2000 ms

Memory limit 262144 kB

Source Educational Codeforces Round 69 (Rated for Div. 2)

Tags dp greedy math *1900

Editorial Announcement (en) Tutorial #1 (en) Tutorial #2 (en) Tutorial #3 (ru)

官方题解

At first let's solve this problem when m=1 and k=0 (it is the problem of finding subarray with maximum sum). For each position from 1 to n we want to know the value of maxli=max1ji+1sum(j,i), where sum(l,r)=k=lkrak, and sum(x+1,x)=0.

We will calculate it the following way. maxli will be the maximum of two values:

  • 0 (because we can take segments of length 0);
  • ai+maxli1.

The maximum sum of some subarray is equal to max1inmaxli.

So, now we can calculate the values of besti=max0len,ilenm0(sum(ilenm+1,i)lenk) the same way.

besti is the maximum of two values:

  • 0;
  • sum(im+1,i)k+bestim.

After calculating all values besti we can easily solve this problem. At first, let's iterate over the elements besti. When we fix some element besti, lets iterate over the value len=1,2,,m and update the answer with value besti+sum(ilen,i1)k.

源代码

#include<stdio.h>
#include<algorithm>

int n,m,k;
long long a[300010];
long long dp[300010],ans;
int main()
{
	//freopen("test.in","r",stdin);
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++) scanf("%lld",a+i),a[i]+=a[i-1];
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j+m>=i;j--)
			dp[i]=std::max(dp[i],a[i]-a[j]);
		dp[i]-=k;
		dp[i]=std::max(0LL,dp[i]);
		if(i>m) dp[i]=std::max(dp[i],dp[i-m]+a[i]-a[i-m]-k);
		ans=std::max(dp[i],ans);
	}
	printf("%lld
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/wawcac-blog/p/11237295.html