1 条题解

  • 0
    @ 2025-4-7 21:38:26

    C++ :

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 500 +5;
    const int M = 100 +5;
    const int T = 4000000 +5;
    typedef long long ll;
    ll n,m,t;
    ll a[N];
    ll cnt[T],sum[T],f[T]={0};
    ll l=1,r,q[T];
    inline double getSlope(int u, int v) { return (double) (f[v] + sum[v] - f[u] - sum[u]) / (cnt[u] == cnt[v] ? 1e-9 : cnt[v] - cnt[u]); }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for (int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        sort(a+1,a+n+1);
        // 状态压缩
        ll dd=a[1];
        for (int i=1;i<=n;i++)
        {
            a[i]-=dd;
            if (a[i]-a[i-1]>2*m)
            {
                dd+=a[i]-a[i-1]-2*m;
                a[i]=a[i-1]+2*m;
            }
            cnt[a[i]]++;
            sum[a[i]]+=a[i];
        }
        t=a[n];
        // 求前缀和
        for (int i=1;i<=t+m;i++)
            cnt[i]+=cnt[i-1],sum[i]+=sum[i-1];
        // DP
        l=1;r=0;
        for (int i=0;i<=t+m;i++)
        {
            if (i-m>=0)
            {
                while (l<r&&getSlope(q[r-1],q[r])>=getSlope(q[r],i-m)) r--;
                q[++r]=i-m;
            }
            while (l<r&&getSlope(q[l],q[l+1])<=i) l++;
            f[i]=cnt[i]*i-sum[i];  // 边界情况
            if (l<=r) f[i]=min(f[i],f[q[l]]+(cnt[i]-cnt[q[l]])*i-(sum[i]-sum[q[l]]));
        }
        // 求ans
        ll ans=1ll<<62;
        for (int i=t;i<=t+m;i++)
            ans=min(ans,f[i]);
        printf("%lld",ans);
    }
    
    • 1

    信息

    ID
    1975
    时间
    1000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者