• 「AGC023D」 Go Home


    「AGC023D」 Go Home

    传送门

    神题。

    首先我们可以倒着考虑。

    当车到达最后一栋楼的时候,车上一定只有到这栋楼的员工。

    当车到达倒数第二栋楼的时候,车上一定只有到达剩下两栋楼的员工。

    设这两栋楼分别为 (a,b),且 (x_a<x_b)。如果当前公交车不在 (a,b) 之间,那么直接往一个方向移动肯定是最优秀的。否则,若 (p_a>p_b),则一定会先往 (a) 的方向移动。

    当车到达倒数第三栋楼的时候,车上一定只有到达剩下三栋楼的员工。

    设这三栋楼分别为 (a,b,c),且 (x_a<x_b<x_c)。如果当前公交车不在 (a,c) 之间,那么直接往一个方向移动肯定是最优秀的。

    否则会有一类很特殊的情况:有汽车在 (a,b) 之间,且 (p_a>p_c,p_a<p_b+p_c)。这个时候如果 (c) 把票投给向自己家的方向,反而会使自己到家的时间变晚——汽车会先向 (c) 方向走,再到达 (a) 楼,最后到达 (c) 楼。

    所以 (c) 一定会把票投给向 (a) 方向走。

    我们发现这等价于把 (c) 楼的人全部看作 (a) 楼的人,然后再加上公交车到 (a) 楼的路程,使公交车移动到 (a) 楼。

    然后你会发现我们上面分析的过程可以通过递归来实现,然后这个题就做完了。

    /*---Author:HenryHuang---*/
    /*---Never Settle---*/
    /*---Never Enough---*/
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+5;
    ll x[maxn],p[maxn];
    ll n,s;
    ll calc(ll l,ll r,ll t){
    	if(s<x[l]) return x[r]-s;
    	if(x[r]<s) return s-x[l];
    	if(p[l]>=p[r]){
    		p[l]+=p[r];
    		return calc(l,r-1,l)+(t==r?x[r]-x[l]:0);
    	}
    	else{
    		p[r]+=p[l];
    		return calc(l+1,r,r)+(t==l?x[r]-x[l]:0);
    	}
    }
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0),cout.tie(0);
    	cin>>n>>s;
    	for(int i=1;i<=n;++i){
    		cin>>x[i]>>p[i];
    	}
    	cout<<calc(1,n,p[1]>=p[n]?n:1)<<'
    ';
    	return 0;
    }
    
    在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。
  • 相关阅读:
    隐性改变display类型
    垂直居中-父元素高度确定的多行文本(方法二)
    去掉WIN7 桌面图标的小箭头
    搭建高可用mongodb集群(三)—— 深入副本集内部机制
    搭建高可用mongodb集群(二)—— 副本集
    搭建高可用mongodb集群(一)——配置mongodb
    Linux:Tomcat报错: Error creating bean with name 'mapScheduler' defined in ServletContext resource 的解决方法
    LINUX ORACLE 启动与关闭
    Linux 安装 Oracle 11g R2
    ORACLE 数据库优化原则
  • 原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/solution-AGC023D.html
Copyright © 2020-2023  润新知