agc023D

题目大意

题解

想了一天结果连边都没有挨到

结论:如果a1>=an,则车一定会先去1,之后从1去往n

证明:n=2时满足,n>2时如果车在n-1~n处,因为a1>=an所以1想的话可以直接消掉n的影响,同时2~n-1也会跟着这么做(其实根据题目的描述来说每个人的选择与本轮其他人的选择无关,但是也可以归纳得到)

如果车在n-1之前,则要么会先走到1,要么变成上面的情况

那么n的时间=1的时间+1n距离,n的人一定会希望1的时间尽量早,所以n会支持1,因此可以视作把n的人搬到1,即a1+=an,然后递归往下做,最后ans加上 n的位置-子问题结束后车的位置

a1<an反之同理

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define ll long long
//#define file
using namespace std;

int b[100001],n,i,j,k,l,r,x;
ll a[100001],ans;

int dg(int l,int r)
{
	int X;
	if (x<b[l]) {ans+=b[r]-x;return b[r];}
	if (x>b[r]) {ans+=x-b[l];return b[l];}
	if (a[l]>=a[r])
	{
		a[l]+=a[r];
		ans+=b[r]-dg(l,r-1);
		return b[r];
	}
	else
	{
		a[r]+=a[l];
		ans+=dg(l+1,r)-b[l];
		return b[l];
	}
}

int main()
{
	#ifdef file
	freopen("agc023d.in","r",stdin);
	#endif
	
	scanf("%d%d",&n,&x);
	fo(i,1,n) scanf("%lld%d",&b[i],&a[i]);
	
	dg(1,n);
	printf("%lld
",ans);
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}
原文地址:https://www.cnblogs.com/gmh77/p/13665927.html