1 条题解

  • 0
    @ 2025-8-24 23:02:55

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar ivyjiao
    复活了

    搬运于2025-08-24 23:02:55,当前版本为作者最后更新于2024-11-10 10:16:19,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    看到绝对值先把它拆了,原式等价于:

    $$dp_{i,j} = \begin{cases} a_i+a_j+i-j & j<i,i-j\leq \frac n 2 \\ a_i+a_j+n+j-i & j\frac n 2 \end{cases}$$

    至于 jij\geq i 的情况,显然没有意义,因为我们只需要枚举 j<ij<i 的情况就可以得出答案。

    然后看到环先把它拆成链,nn×2n\gets n\times 2

    那么原式的第二条也没有意义了,变为:

    dpi,j=ai+aj+ij    (j<i,ijn2)dp_{i,j} = a_i+a_j+i-j~~~~(j<i,i-j\leq \frac n 2)

    所以我们要从前往后枚举,此时原式看起来像是单调队列优化,所以考虑变形(从前往后枚举):

    dpi=max{ajj}+ai+i    (ijn2)dp_i = \max\{a_j-j\}+a_i+i~~~~(i-j\leq \frac n 2)

    好了,我们只需要维护 max{aii}\max\{a_i-i\} 就行了,后面的条件就是 pop 队头的条件,队头是最大的 aiia_i-i

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e6+1;
    int n,a[N],q[N],h,t,ans;
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            a[i+n]=a[i];
        }
        for(int i=1;i<=n*2;i++){
            while(h<=t&&i-q[h]>n/2) h++;
            if(h<=t) ans=max(ans,a[i]+a[q[h]]+i-q[h]);
            while(h<=t&&a[q[t]]-q[t]<=a[i]-i) t--;
            q[++t]=i;
        }
        cout<<ans;
    }
    
    • 1

    信息

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