zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    【Leetcode】【Easy】Remove Duplicates from Sorted List
    【Leetcode】【Easy】Pascal's Triangle II
    【Leetcode】【Easy】Pascal's Triangle
    【Leetcode】【Easy】Binary Tree Level Order Traversal II
    【Leetcode】【Easy】Binary Tree Level Order Traversal
    【Leetcode】【Easy】Maximum Depth of Binary Tree
    【Leetcode】【Easy】Minimum Depth of Binary Tree
    【Leetcode】【Easy】Balanced Binary Tree
    【Leetcode】【Easy】Symmetric Tree
    如何使用Action.Invoke()触发一个Storyboard
  • 原文地址:https://www.cnblogs.com/mmlz/p/6388385.html
Copyright © 2011-2022 走看看