• UVALive4374 Drive through MegaCity


    题目戳这里

    首先我们对坐标进行离散化,有用的点就变成了(O(N))个。我们假设(A)(B)的右边(从(A)(B)跑和从(B)(A)跑等价),然后我们很容易发现不会往左跑。于是我们就可以dp了。我们用(f[i][j])表示(A)((i,j))的最小代价(((i,j))是离散后的坐标),然后我们很容易得到dp方程。

    [f[i][j] = min { f[i-1][j]+Tx[i-1][j] imes (x[i]-x[i-1]),\f[i][j+1]+Ty[i][j] imes (y[j+1]-y[j]),f[i][j-1]+Ty[i][j-1]+(y[j]-y[j-1]) } ]

    其中(Tx[i][j])表示从((i,j))走到((i+1,j))走一个单位所需要的时间,(Ty[i][j])表示从((i,j))走到((i,j+1))一个单位所需要的时间。这个我们可以预处理出来(大致就是看这中间有没有点在矩形的边界或中间)。

    然后若(B)(A)下方,则还可能只向下向左向右走。我们可以旋转坐标,就跟上面的一样处理了。

    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    typedef long long ll;
    const int maxn = 2010; const ll inf = 1LL<<60;
    int Xa,Ya,Xb,Yb,N,totx,toty,bacx[maxn],bacy[maxn],in[maxn][maxn],Lb[maxn][maxn],Db[maxn][maxn];
    ll f[maxn][maxn],Tx[maxn][maxn],Ty[maxn][maxn],ans;
    
    inline int gi()
    {
    	char ch; int ret = 0,f = 1;
    	do ch = getchar(); while (!(ch >= '0'&&ch <= '9')&&ch != '-');
    	if (ch == '-') f = -1,ch = getchar();
    	do ret = ret*10+ch-'0',ch = getchar(); while (ch >= '0'&&ch <= '9');
    	return ret*f;
    }
    
    struct Node
    {
    	int X1,Y1,X2,Y2,T;
    	inline void read()
    	{
    		bacx[++totx] = X1 = gi(); bacy[++toty] = Y1 = gi();
    		bacx[++totx] = X2 = gi(); bacy[++toty] = Y2 = gi();
    		T = gi();
    	}
    	inline void convert() { swap(X1,Y1); swap(X2,Y2); }
    }rec[maxn];
    
    inline int find(int arr[],int r,int key)
    {
    	int l = 1,mid;
    	while (l <= r)
    	{
    		mid = (l+r) >> 1;
    		if (arr[mid] < key) l = mid+1;
    		else r = mid-1;
    	}
    	return l;
    }
    	
    inline void work(int xx[],int tx,int yy[],int ty)
    {
    	for (int i = 1;i <= tx;++i) for (int j = 1;j <= ty;++j) Lb[i][j] = Db[i][j] = in[i][j] = 0;
    	for (int i = 1;i <= N;++i)
    	{
    		int pX1 = find(xx,tx,rec[i].X1),pX2 = find(xx,tx,rec[i].X2);
    		int pY1 = find(yy,ty,rec[i].Y1),pY2 = find(yy,ty,rec[i].Y2);
    		for (int j = pX1+1;j < pX2;++j)
    			for (int k = pY1+1;k < pY2;++k) in[j][k] = i;
    		for (int k = pY1+1;k < pY2;++k) Lb[pX1][k] = i;
    		for (int j = pX1+1;j < pX2;++j) Db[j][pY1] = i;
    	}
    	for (int i = 1;i <= tx;++i)
    		for (int j = 1;j <= ty;++j)
    		{
    			if (i < tx)
    			{
    				Tx[i][j] = 10;
    				if (in[i][j]) Tx[i][j] = rec[in[i][j]].T;
    				else if (in[i+1][j]) Tx[i][j] = rec[in[i+1][j]].T;
    				else if (Lb[i][j]) Tx[i][j] = rec[Lb[i][j]].T;
    			}
    			if (j < ty)
    			{
    				Ty[i][j] = 10;
    				if (in[i][j]) Ty[i][j] = rec[in[i][j]].T;
    				else if (in[i][j+1]) Ty[i][j] = rec[in[i][j+1]].T;
    				else if (Db[i][j]) Ty[i][j] = rec[Db[i][j]].T;
    			}
    		}
    	if (Xa > Xb) swap(Xa,Xb),swap(Ya,Yb);
    	
    	for (int i = 1;i <= tx;++i) for (int j = 1;j <= ty;++j) f[i][j] = inf;
    	f[find(xx,tx,Xa)][find(yy,ty,Ya)] = 0;
    	for (int i = 2;i <= tx;++i)
    	{
    		for (int j = 1;j <= ty;++j)
    		{
    			f[i][j] = min(f[i-1][j]+Tx[i-1][j]*(xx[i]-xx[i-1]),f[i][j]);
    			if (j > 1) f[i][j] = min(f[i][j],f[i][j-1]+Ty[i][j-1]*(yy[j]-yy[j-1]));
    		}
    		for (int j = ty;j;--j) if (j < ty) f[i][j] = min(f[i][j],f[i][j+1]+Ty[i][j]*(yy[j+1]-yy[j]));
    	}
    	ans = min(ans,f[find(xx,tx,Xb)][find(yy,ty,Yb)]);
    }
    
    int main()
    {
    	freopen("4374.in","r",stdin);
    	freopen("4374.out","w",stdout);
    	while (scanf("%d %d %d %d",&Xa,&Ya,&Xb,&Yb) != EOF)
    	{
    		totx = toty = 0; N = gi(); ans = inf;
    		bacx[++totx] = Xa; bacx[++totx] = Xb;
    		bacy[++toty] = Ya; bacy[++toty] = Yb;
    		for (int i = 1;i <= N;++i) rec[i].read();
    
    		sort(bacx+1,bacx+totx+1); sort(bacy+1,bacy+toty+1);
    		totx = unique(bacx+1,bacx+totx+1)-bacx-1; toty = unique(bacy+1,bacy+toty+1)-bacy-1;
    	
    		work(bacx,totx,bacy,toty);
    
    		swap(Xa,Ya); swap(Xb,Yb);
    		for (int i = 1;i <= N;++i) rec[i].convert();
    		work(bacy,toty,bacx,totx);
    		cout << ans << endl;		
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    用户空间与内核空间,进程上下文与中断上下文[总结]【转】
    select、poll、epoll之间的区别总结[整理]【转】
    v4l2驱动文档之——streaming IO【转】
    Linux网络编程一步一步学【转】
    V4L2驱动的移植与应用(二+三)【转】
    【PHP面向对象(OOP)编程入门教程】20.PHP5接口技术(interface)
    【PHP面向对象(OOP)编程入门教程】19.抽象方法和抽象类(abstract)
    【PHP面向对象(OOP)编程入门教程】18.__call()处理调用错误
    【PHP面向对象(OOP)编程入门教程】17.克隆对象__clone()方法
    【PHP面向对象(OOP)编程入门教程】16.__toString()方法
  • 原文地址:https://www.cnblogs.com/mmlz/p/6388385.html
Copyright © 2020-2023  润新知