• 环路运输


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

      

  • 相关阅读:
    Android MediaPlayer
    MediaPlayer基本使用方式
    css 透明度 一句话搞定透明背景!
    CSS ZOOM 作用[IE6下清除浮动]
    document.execcommand方法
    让position:fixed在IE6下可用
    CSS文档流与块级元素(block)内联元素(inline)那点事
    Android屏幕分辨率详解(VGA、HVGA、QVGA、WVGA、WQVGA)
    重载的乐趣
    线程间调用不同线程创建的控件
  • 原文地址:https://www.cnblogs.com/cutemush/p/13628077.html
Copyright © 2020-2023  润新知