环路运输
在一条环形公路旁均匀地分布着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); }