P10957 环路运输 题解
前置知识
解法
在仓库 \(1\) 和 \(n\) 之间把环断开,然后复制一倍接在末尾,形成长度为 \(2n\) 的直线公路,即有 \(a_{i}=a_{i+n} (1 \le i \le n)\)。
对于原来环形公路上的任意两座仓库 \(i,j(1 \le j<i \le n)\),代价为 \(\begin{cases} a_{i}+a_{j}+i-j & i-j \le \frac{n}{2} \\ a_{j+n}+a_{i}+j+n-i & i-j> \frac{n}{2} \end{cases}\)。即对于直线公路上的任意两座仓库 \(i,j(1 \le j<i \le 2n,i-j \le \frac{n}{2})\),代价为 \(a_{i}+a_{j}+i-j\)。
单调队列维护递增的 \(a_{i}-i\) 即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
int a[2000010];
deque<int>q;
int main()
{
int n,ans=0,i;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[i];
a[i+n]=a[i];
}
for(i=1;i<=2*n;i++)
{
while(q.empty()==0&&i-q.front()>n/2)
{
q.pop_front();
}
if(q.empty()==0)
{
ans=max(ans,a[i]+a[q.front()]+i-q.front());
}
while(q.empty()==0&&a[q.back()]-q.back()<=a[i]-i)
{
q.pop_back();
}
q.push_back(i);
}
cout<<ans<<endl;
return 0;
}
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18378261,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。