2018 ACM-ICPC 南京站 B Tournament dp+决策单调性+wqs二分

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fanbaobao829/article/details/83118460
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3f
#define N 10010
ll n,k,s[N],f[N],w[N],ans=0,q[N];
inline ll calc(ll j,ll i)
{
    ll mid=i+j+1>>1;
    ll now=s[mid]-s[mid-1];
    return f[j]+s[i]+s[j]-2*s[mid]+((i-j)&1?now:0);
}
inline bool better(ll k1,ll k2,ll i)
{
    ll val1=calc(k1,i),val2=calc(k2,i);
    if(val2<val1)
        return 1;
    if(val1<val2)
        return 0;
    return w[k2]<=w[k1];
}
inline ll bettert(ll k1,ll k2)
{
    ll l=k2+1,r=n;
    while(l<=r)
    {
        ll mid=l+r>>1;
        if(better(k1,k2,mid))
            r=mid-1;
        else
            l=mid+1;
    }
    return r+1;
}
inline ll jud(ll mid)
{
    ll qh=1,qt=0;
    q[++qt]=0;
    for(ll i=1;i<=n;++i)
    {
        while(qh<qt&&better(q[qh],q[qh+1],i))
            ++qh;
        f[i]=calc(q[qh],i)+mid;
        w[i]=w[q[qh]]+1;
        while(qh<qt&&bettert(q[qt-1],q[qt])>bettert(q[qt],i))
            --qt;
        q[++qt]=i;
    }
    return w[n];
}
int main()
{
    while(scanf("%lld%lld",&n,&k)!=EOF)
    {
        ans=0;
        for(ll i=1;i<=n;i++)
        {
            scanf("%lld",s+i);
            s[i]+=s[i-1];
        }
        ll l=0,r=s[n]*s[n];
        while(l<=r)
        {
            ll mid=l+r>>1;
            if(jud(mid)<=k)
            {
                r=mid-1;
                ans=f[n]-k*mid;
            }
            else
                l=mid+1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}
/*
5 2
0 4 7 9 10
9 3
0 1 10 11 20 21 22 30 32
*/

猜你喜欢

转载自blog.csdn.net/fanbaobao829/article/details/83118460
今日推荐