【JZOJ3187】的士

版权声明:欢迎dalao指出错误暴踩本SD,蒟蒻写的博客转载也要吱一声 https://blog.csdn.net/enjoy_pascal/article/details/88913140

description

Bessie为农场上的其他奶牛提供的士服务。奶牛们在一条长为M(1<=M<=1,000,000,000)的栅栏的不同位置上。不幸的是,它们厌倦了它们现在所在的位置而想要去栅栏上其他的位置。Bessie必须把她每一个朋友从它们各自的起始地接上车然后送它们到目的地。但Bessie的车太小了,所以她每次只能运送一只奶牛。奶牛们上车下车是瞬间的事情。

为了省油钱,Bessie想要使她的驾驶量最小。给出N只奶牛(1<=N<=100,000)每一只的起始地和目的地,计算Bessie最少需要的驾驶量。Bessie意识到她需要偶尔把牛放在某一个地方而不是把它送到目的地才能省油钱。

Bessie在栅栏最左端(位置0)开始工作,而且必须在最右端(位置M)结束她的工作。


analysis

  • 首先所有的路程是一定要走完一次的,那么考虑走剩下的空车路程

  • 对于两个路程,考虑是送完一头牛去找下一头,那么前面的尾越接近后面的头越优

  • 那么排序两个头和尾,加一条 m m 0 0 的路,然后一一配对,因为这是最优的

  • 正确性不显然


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define MAXN 1000005
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))

using namespace std;

ll s[MAXN],t[MAXN];
ll n,m,ans;

O3 inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
	while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
O3 int main()
{
	//freopen("T1.in","r",stdin);
	n=read(),m=read(),s[0]=m;
	fo(i,1,n)s[i]=read(),t[i]=read(),ans+=abs(s[i]-t[i]);
	sort(s,s+n+1),sort(t,t+n+1);
	fo(i,0,n)ans+=abs(s[i]-t[i]);
	printf("%lld\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/enjoy_pascal/article/details/88913140