【单调队列优化DP】CH 5501 环路运输

链接

http://contest-hunter.org:83/contest/0x50%E3%80%8C%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E3%80%8D%E4%BE%8B%E9%A2%98/5501%20%E7%8E%AF%E8%B7%AF%E8%BF%90%E8%BE%93


大意

给定一个长度为 n n 的环形序列 a a ,定义 dist(i,j)=min(|ij|,n|ij|) d i s t ( i , j ) = m i n ( | i − j | , n − | i − j | ) ,求出最大的
Ai+Aj+dist(i,j) A i + A j + d i s t ( i , j )


思路

破环为链
判断长度是否超过 n/2 n / 2 (因为这样)
然后题目就可以转换乘最大子序和的问题了
用单调队列优化一下即可


代码

#include
#include
#include
using namespace std;int a[2000001],n,ans;
deque<int>q;
int read()
{
    int f=0;char c;
    while(c=getchar(),c<=47||c>=58);f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),c>=48&&c<=57) f=(f<<3)+(f<<1)+c-48;
    return f;
}
signed main()
{
    n=read();
    for(register int i=1;i<=n;i++) a[i+n]=a[i]=read();
    for(register int i=1;i<=(n<<1);i++)
    {
        while(q.size()&&i-q.front()>n/2) q.pop_front();
        if(q.size())ans=max(ans,a[i]+a[q.front()]+i-q.front());
        while(q.size()&&a[q.back()]-q.back()<=(a[i]-i)) q.pop_back();
        q.push_back(i);
    }
    printf("%d",ans);
}

你可能感兴趣的:(dp)