zoukankan      html  css  js  c++  java
  • 【UOJ #107】【APIO 2013】ROBOTS

    http://uoj.ac/problem/107
    (f(l,r,i,j))表示([l,r])中的机器人聚集到((i,j))需要花的最小操作数。
    (f(l,r,i,j)=minleft{egin{array}{rcl} f(l,k,i,j)+f(k+1,r,i,j)\ f(l,r,i',j'),(i',j') ightarrow(i,j)end{array} ight.)
    斯坦纳树的模型,对于每个([l,r])的状态,处理完第一行后再跑一遍双队列广搜处理第二行。
    用基数排序优化,时间复杂度(O(n^3+n^2hw))

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N = 503;
    const int dx[4] = {-1, 0, 1, 0};
    const int dy[4] = {0, -1, 0, 1};
    
    struct data {
    	int x, y;
    	data (int _x = 0, int _y = 0) : x(_x), y(_y) {}
    } to[N][N][4];
    
    bool vis[N][N][4];
    char s[N][N];
    int f[10][10][N][N], n, w, h;
    
    data work(int x, int y, int tmp) {
    	if (vis[x][y][tmp]) return to[x][y][tmp];
    	vis[x][y][tmp] = true;
    	if (s[x][y] == 'A') (++tmp) &= 3;
    	if (s[x][y] == 'C') (--tmp) &= 3;
    	if (s[x + dx[tmp]][y + dy[tmp]] == 'x')
    		return data(x, y);
    	else
    		return to[x + dx[tmp]][y + dy[tmp]][tmp] = work(x + dx[tmp], y + dy[tmp], tmp);
    }
    
    int tot = 0, l, r, id[N * N];
    data q1[N * N], q2[N * N], tt;
    
    template <typename T> void check_min(T &a, T b) {if (b < a) a = b;}
    template <typename T> void check_max(T &a, T b) {if (b > a) a = b;}
    
    bool cmp(data A, data B) {return f[l][r][A.x][A.y] < f[l][r][B.x][B.y];}
    
    int c[N * N * 20];
    
    void BFS() {
    //	stable_sort(q1 + 1, q1 + tot + 1, cmp);
    	int mx = 0, num;
    	for (int i = 1; i <= tot; ++i) if ((num = f[l][r][q1[i].x][q1[i].y]) != 1010580540) check_max(mx, num);
    	memset(c, 0, sizeof(int) * (mx + 2));
    	for (int i = 1; i <= tot; ++i) {
    		num = f[l][r][q1[i].x][q1[i].y];
    		if (num != 1010580540) ++c[num];
    		else ++c[mx + 1];
    	}
    	for (int i = 1; i <= mx + 1; ++i) c[i] += c[i - 1];
    	for (int i = tot; i >= 1; --i) {
    		num = f[l][r][q1[i].x][q1[i].y];
    		if (num == 1010580540) num = mx + 1;
    		id[c[num]--] = i;
    	}
    	int head = 1, tail = 0, tmp = 1, x, y, x2, y2;
    	while (head <= tail || tmp <= tot) {
    		x = q2[head].x; y = q2[head].y;
    		x2 = q1[id[tmp]].x; y2 = q1[id[tmp]].y;
    		if (head <= tail && tmp <= tot && f[l][r][x][y] < f[l][r][x2][y2] || tmp > tot)	++head;
    		else ++tmp, x = x2, y = y2;
    		for (int d = 0; d < 4; ++d) {
    			tt = to[x][y][d];
    			if (tt.x == 0) continue;
    			if (f[l][r][tt.x][tt.y] > f[l][r][x][y] + 1) {
    				f[l][r][tt.x][tt.y] = f[l][r][x][y] + 1;
    				q2[++tail] = tt;
    			}
    		}
    	}
    }
    
    int main() {
    	scanf("%d%d%d", &n, &w, &h);
    	
    	memset(f, 60, sizeof(f));
    	
    	for (int i = 1; i <= h; ++i)
    		scanf("%s", s[i] + 1);
    	for (int i = 1; i <= h; ++i) s[i][0] = s[i][w + 1] = 'x';
    	for (int i = 1; i <= w; ++i) s[0][i] = s[h + 1][i] = 'x';
    	for (int i = 1 ; i <= h; ++i)
    		for (int j = 1; j <= w; ++j)
    			if (s[i][j] != 'x')
    				for (int dt = 0; dt < 4; ++dt)
    					to[i][j][dt] = work(i, j, dt);
    	
    	for (int i = 1; i <= h; ++i)
    		for (int j = 1; j <= w; ++j) q1[++tot] = data(i, j);
    	
    	bool flag;
    	for (int i = n; i >= 1; --i) {
    		flag = false;
    		for (int ii = 1; ii <= h; ++ii) {
    			for (int jj = 1; jj <= w; ++jj)
    				if (s[ii][jj] == '0' + i) {
    					f[i][i][ii][jj] = 0;
    					flag = true;
    					break;
    				}
    			if (flag) break;
    		}
    		l = r = i; BFS();
    		for (int j = i + 1; j <= n; ++j) {
    			for (int k = i; k < j; ++k)
    				for (int ii = 1; ii <= h; ++ii)
    					for (int jj = 1; jj <= w; ++jj)
    						check_min(f[i][j][ii][jj], f[i][k][ii][jj] + f[k + 1][j][ii][jj]);
    			l = i; r = j; BFS();
    		}
    	}
    	
    	int ans = 0x7fffffff;
    	for (int i = 1; i <= h; ++i)
    		for (int j = 1; j <= w; ++j)
    			check_min(ans, f[1][n][i][j]);
    	printf("%d
    ", ans == 1010580540 ? -1 : ans);
    	return 0;
    }
    
  • 相关阅读:
    xampp只允许本地访问,禁止远程访问
    Centos 7 安装 设置 IP地址,DNS,主机名,防火墙,端口,SELinux (实测+笔记)
    centos 7.0 网卡配置及重命名教程
    VS2010 安装 MVC3 Entity Framework
    SQL 增加删除库表
    轻松绕各种WAF的POST注入、跨站防御(比如安全狗)
    CRM协同8.2升级到9.2SP2步骤
    [转]EasyUI+MVC+EF简单用户管理Demo(问题及解决)
    设置VMware随系统开机自动启动并引导虚拟机操作系统
    项目管理——随笔 2015.06.05
  • 原文地址:https://www.cnblogs.com/abclzr/p/6706229.html
Copyright © 2011-2022 走看看