这道题值得好好想一会
我们通过对一些小数据的手算,以及对于每段路程的拆分,可以发现:
1.每个st对应的ed这段路程无论如何都要算上
2.额外还要计算的一段路程,就是“切换”费用
什么是切换费用呢?
我们知道可能会有这样的位置st,到达该位置时,把已经在车上的牛 i 扔下去,载上该处的牛 j 并将它运到其终点ed再回来把牛 i 载上
那么我们就需要再加上每一对abs(ed-st)的和
具体实现,我们需要在st、ed中再加上终点m,起点0,
但是要注意的是,0加到ed里,m加到st里
原因在于我们需要从起点0走到最近的st,从最远的ed走到m
所以0对应的就是min_st,0必然在ed里的第一个;m也一样
最后将st,ed排序,枚举累加即可


1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=100010; 6 int n,m,st[N],ed[N]; 7 long long ans=0; 8 int read(){ 9 int sum=0; 10 char ch=getchar(); 11 while (ch<'0'||ch>'9') 12 ch=getchar(); 13 while (ch>='0'&&ch<='9'){ 14 sum=sum*10+ch-'0'; 15 ch=getchar(); 16 } 17 return sum; 18 } 19 int main(){ 20 n=read(); 21 m=read(); 22 for (int i=1;i<=n;i++){ 23 st[i]=read(); 24 ed[i]=read(); 25 ans+=abs(st[i]-ed[i]); 26 } 27 st[n+1]=m;//最远的ed开到m 28 ed[n+1]=0;//0开到最近的st 29 sort(st+1,st+n+2); 30 sort(ed+1,ed+n+2); 31 for (int i=1;i<=n+1;i++) 32 ans+=abs(ed[i]-st[i]); 33 printf("%lld",ans); 34 return 0; 35 }