在一条环形公路旁均匀地分布着N座仓库,编号为1~N,编号为 i 的仓库与编号为 j 的仓库之间的距离定义为 dist(i,j)=min(|i-j|,N-|i-j|),也就是逆时针或顺时针从i到j中较近的一种。每座仓库都存有货物,其中编号为i的仓库库存量为A_i。在i和j两座仓库之间运送货物需要的代价为A_i+A_j+dist(i,j)。求在哪两座仓库之间运送货物需要的代价最大。
输入
第一行一个整数N,第二行N个整数A1~AN。
1≤N≤10^6,1<=Ai<=10^7
输出
一个整数,表示最大代价。
样例输入
5
1 8 6 2 5
样例输出
15
//在第2个仓库到第5个仓库之间进行运输货物
Sol:
ans=a[i]+i+a[j]-j,于是针对a[j]-j这个属性维护一个单调队列 ,另此题是一个环,于是破环为链就好了。
//ans=a[i]+i+a[j]-j,于是针对a[j]-j这个属性维护一个单调队列
#include <bits/stdc++.h>
using namespace std;
int in(){
int ans=0; char c=getchar();
while (c<48||c>57) c=getchar();
while (c>47&&c<58) ans=ans*10+c-48,c=getchar();
return ans;
}
int n,a[2000001],q[2000001],head,tail,ans;
int max(int a,int b){return (a>b)?a:b;}
int main(){
n=in(); head=1;
for (int i=1;i<=n;i++) a[i]=a[i+n]=in();
for (int i=1;i<(n<<1);i++)
{
// cout<<"i is "<<i<<endl;
while (head<=tail&&i-q[head]>(n>>1))
//如果当前点与队列中头结点距离超过n/2
head++;
// cout<<"before the queue is "<<endl;
// for (int j=head;j<=tail;j++)
// cout<<q[j]<<" "<<a[q[j]]-q[j]<<endl;
// cout<<endl;
// system("pause");
ans=max(ans,a[i]+i+a[q[head]]-q[head]); //取最优值
while (head<=tail&&a[i]-i>=a[q[tail]]-q[tail])
//维护一个单调下降队列,队首值是最大的
tail--;
q[++tail]=i;
// cout<<"after the queue is "<<endl;
// for (int j=head;j<=tail;j++)
// cout<<q[j]<<" "<<a[q[j]]-q[j]<<endl;
// cout<<endl;
}
return !printf("%d",ans);
}