D. The Best Vacation
大致题意:规定一个日历有 个月,每个月有
天,在第
个月的第
天活动你可以获得
的贡献,你只能连续
天活动,请问你能获得的最大贡献是多少.
分析:
方法一:尺取法.
考虑我们选的天数是连续,那么对应月份也是连续的,并且假设中间月份的天数都是取得到的,但是还可以再两边去取天数,显然我们应该是去最左边的天数,因为贡献是从 开始递减的,而右边的天数是从
开始递增的。
那么我们依次遍历月份,用双指针去维护可满足的连续天数并计算对应贡献.
但是月份天数就跟环一样,是首尾相接的,对于环而言的尺取,我们一般都是多开一倍空间,数组循环一遍,然后从 的位置开始计算贡献(这样可以算得当前选择方案是部分最优).维护连续天数我们可以用两个前缀和进行维护。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int n;
ll x,a[maxn<<1],sum1[maxn<<1],sum2[maxn<<1],ans;
int main()
{
scanf("%d%lld",&n,&x);
for( int i=1;i<=n;i++ ) scanf("%lld",&a[i]),a[n+i]=a[i];
for( int i=1;i<=2*n;i++ )
{
sum1[i]=sum1[i-1]+a[i];
sum2[i]=sum2[i-1]+a[i]*(a[i]+1)/2;
}
int j=0;
for( int i=1;i<=2*n;i++ )
{
while( sum1[i]-sum1[j]>x ) ++j;
if( i>n )
{
ll val=sum2[i]-sum2[j];
ll l=x-(sum1[i]-sum1[j]);
val+=(a[j]-l+1+a[j])*l/2;
ans=max(ans,val);
}
}
printf("%lld\n",ans);
return 0;
} 
京公网安备 11010502036488号