• POJ 2688 Cleaning Robot(BFS + A* + 状态压缩DP)


    题意:

    给你一个N * M(1 ≤ N, M ≤ 20)的地图,'.'表示空位,'*'表示垃圾,'o'表示机器人的初始位置,'x'表示墙。请你计算机器人清理完所有的垃圾至少要走多少步。

    机器人一旦走到垃圾上,垃圾就被清掉了。输入数据保证垃圾不多于10个。

    思路:

    1. 先 BFS 求出任意两个污点间所需要的最小步数。题目保证了污点数不超过 10 个,这时候可以应用经典的 TSP 模型,用状态压缩 dp 解决之;

    2. dp[u][s] 代表以 u 结束的状态 s 需要经过的最小步数。 s 中的位代表已经选择了的污点,初始状态 dp[0][0] = 0, 其他赋值 INFS,求解 dp[i][ends] 最小值。

     

    #include <iostream>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    const int INFS = 0x3fffffff;
    const int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
    char grid[25][25];
    int col, row, dis[15][15];
    bool vis[25][25];
    
    struct Dirty {
        int x, y;
    } dirty[20] ;
    
    struct ST {
        int x, y, step, f;
        ST(int _x, int _y, int _step, int _f) : x(_x), y(_y), step(_step), f(_f) {}
        bool operator < (const ST& other) const {
            return f > other.f;
        }
    };
    
    bool judge(int x, int y) {
        if (0 < x && x <= row && 0 < y && y <= col && grid[x][y] != 'x') {
            return true;
        }
        return false;
    }
    
    int getdiff(const Dirty& a, const Dirty& b) {
        return abs(a.x - b.x) + abs(a.y - b.y);
    }
    
    int bfs(const Dirty& src, const Dirty& dst) {
        priority_queue<ST> Q;
        Q.push(ST(src.x, src.y, 0, getdiff(src, dst)));
        memset(vis, false, sizeof(vis));
        vis[src.x][src.y] = true;
    
        while (!Q.empty()) {
            ST u = Q.top();
            Q.pop();
    
            if (u.x == dst.x && u.y == dst.y)
                return u.step;
    
            for (int i = 0; i < 4; i++) {
                Dirty v;
                v.x = u.x + dir[i][0];
                v.y = u.y + dir[i][1];
                if (judge(v.x, v.y) && !vis[v.x][v.y]) {
                    vis[v.x][v.y] = true;
                    int f = u.step + 1 + getdiff(v, dst);
                    Q.push(ST(v.x, v.y, u.step + 1, f));
                }
            }
        }
        return -1;
    }
    
    int dp[12][1<<12];
    int dirtycnt;
    
    inline int getflag(int r) {
        return 1 << r;
    }
    
    int dfs(int state, int u) {
        if (dp[u][state] != INFS)
            return dp[u][state];
    
        int s = state ^ getflag(u - 1);
        if (s == 0) 
            return dis[0][u];
    
        for (int i = 1; i <= dirtycnt; i++) {
            if (s & getflag(i-1)) {
                dp[u][state] = min(dp[u][state], dfs(s, i) + dis[i][u]);
            }
        }
        return dp[u][state];
    }
    
    int main() {
        while (scanf("%d%d", &col, &row) && col && row) {
            memset(dirty, 0, sizeof(dirty));
            dirtycnt = 0;
            for (int i = 1; i <= row; i++) { 
                scanf("%s", &grid[i][1]);
                for (int j = 1; j <= col; j++) {
                    if (grid[i][j] == '*') {
                        dirtycnt += 1;
                        dirty[dirtycnt].x = i;
                        dirty[dirtycnt].y = j;
                    } else if (grid[i][j] == 'o') {
                        dirty[0].x = i; dirty[0].y = j;
                    }
                }
            }
    
            bool flag = false;
            for (int i = 0; i <= dirtycnt; i++) {
                for (int j = i; j <= dirtycnt; j++) {
                    if (i == j) {
                        dis[i][j] = 0;
                    } else {
                        dis[j][i] = dis[i][j] = bfs(dirty[i], dirty[j]);
                        if (dis[i][j] == -1) {
                            flag = true; break; 
                        }
                    }
                }
            }
            if (flag) {
                printf("-1\n"); continue;
            }
    
            int ends = getflag(dirtycnt) - 1;
            for (int i = 0; i <= dirtycnt; i++) {
                for (int j = 0; j <= ends; j++)
                    dp[i][j] = INFS;
            }
            dp[0][0] = 0;
            int ans = INFS;
            for (int i = 1; i <= dirtycnt; i++)
                ans = min(ans, dfs(ends, i));
            printf("%d\n", ans);
        }
        return 0;
    }
  • 相关阅读:
    IOS开发中UITableView(表视图)的滚动优化及自定义Cell
    IOS软件国际化(本地化Localizable)
    IOS三种归档(NSKeyArchieve)的总结
    在IOS中使用DES算法对Sqlite数据库进行内容加密存储并读取解密
    内存管理_缓存一致性
    JAVA volatile 关键字
    C++ STL 的实现:
    Java for LeetCode 236 Lowest Common Ancestor of a Binary Tree
    Java for LeetCode 235 Lowest Common Ancestor of a Binary Search Tree
    Java for LeetCode 234 Palindrome Linked List
  • 原文地址:https://www.cnblogs.com/kedebug/p/2979951.html
Copyright © 2020-2023  润新知