D. Dog Walking

我们知道在最大值和最小值之外我们进行加减对答案是不影响的,而对于两个极值内部,我们一定会让他尽最大努力向一个方向走,因此我们可以把同一方向的放在一块。

但是我们不知道极值在哪里,只知道结构,所以我们循环整个取值去尝试找到最大值就好了,答案一定是其中之一的情况

/*input
3 100
1 2 -3

*/

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=3010;
int a[N],b;
int p[N];
ll mx(int n)
{
    ll ans=0;
    for(int i=0;i<b+1;i++)
    {
        ll l=0,r=0,idx=0,c=0;
        for(int j=1;j<=n;j++)
        {
            if(a[j]) idx+=a[j];
            else idx+=p[(c+i)%b],c++;
            l=min(l,idx);
            r=max(r,idx);
        }
        ans=max(ans,r-l+1);
    }
    return ans;
}
int main()
{
    ll n,m;
    ll sum=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        cin>>a[i];  sum+=a[i];
        if(a[i]==0) b++;
    }
    if(abs(sum)>1ll*b*m) 
        cout<<-1<<endl;
    else{
        ll ans=0;
        ll q=abs(sum);
        for(int i=0;i<b;i++)
        {
            if(q+m<=(b-i-1)*m) p[i]=m,q+=m;
            else if(q>0)
            {
                if(q%m==0) p[i]=-m,q-=m;
                else p[i]=-q%m,q+=p[i];
            }
            if(sum<0) p[i]=-p[i];
        }

        ll test=sum;
        for(int i=0;i<b;i++) test+=p[i];
        if(test==0) ans=max(ans,mx(n));
        for(int i=0;i<b;i++) p[i]=0;
        q=abs(sum);
        for(int i=0;i<b;i++)
        {
            if(m-q<=(b-i-1)*m) p[i]=-m,q-=m;
            else if(q<0)
            {
                if(q%m==0) p[i]=m,q+=m;
                else p[i]=-q%m,q+=p[i];
            }
            if(sum<0) p[i]=-p[i];
        }

        test=sum;
        for(int i=0;i<b;i++) test+=p[i];
        if(test==0) ans=max(ans,mx(n));
        cout<<ans<<endl;
    } 



}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值