zoukankan      html  css  js  c++  java
  • hdu 4770 Lights Against Dudely(回溯)

    题目链接:hdu 4770 Lights Against Dudely

    题目大意:在一个N*M的银行里。有N*M个房间,‘#’代表牢固的房间,‘.‘代表的是脆弱的房间。脆弱的房间个数不会超过15个,如今为了确保安全,要在若干个脆弱的房间上装灯。普通的灯是照亮{0, 0}, {-1, 0}, {0, 1}(和题目中坐标有点出入)。然后能够装一个特殊的,能够照耀

    • { {0, 0}, {0, 1}, {1, 0} },
    • { {0, 0}, {-1, 0}, {0, -1} },
    • { {0, 0}, {0, -1}, {1, 0} }
      同一个房间不能够装两栈灯,灯光不能照耀牢固的房间,问说最少须要多少栈灯。

    解题思路:dfs+剪枝。暴力枚举放特殊灯的位置,然后将脆弱房间依照i坐标大放前面,相等的将j坐标小的方前面,这样做是为了dfs的时候剪枝,仅仅要碰到一个房间不能放就返回。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int maxn = 200;
    const int maxv = 20;
    const int INF = 0x3f3f3f3f;
    const int dir[4][3][2] = { { {0, 0}, {-1, 0}, {0, 1} },
                               { {0, 0}, {0, 1}, {1, 0} },
                               { {0, 0}, {-1, 0}, {0, -1} },
                               { {0, 0}, {0, -1}, {1, 0} }
                            };
    
    int ans;
    int n, N, M, x[maxv], y[maxv], c[maxv];
    int v[maxn+5][maxn+5];
    char g[maxn+5][maxn+5];
    
    inline int judge (int xi, int yi, const int d[3][2]) {
    
        for (int i = 0; i < 3; i++) {
            int p = xi + d[i][0];
            int q = yi + d[i][1];
    
            if (p <= 0 || p > N)
                continue;
    
            if (q <= 0 || q > M)
                continue;
    
            if (g[p][q] == '#')
                return 0;
        }
        return 1;
    }
    
    inline void set (int xi, int yi, const int d[3][2], int type) {
        for (int i = 0; i < 3; i++) {
            int p = xi + d[i][0];
            int q = yi + d[i][1];
    
            if (p <= 0 || p > N)
                continue;
    
            if (q <= 0 || q > M)
                continue;
    
            v[p][q] = type;
        }
    }
    
    void init () {
        n = 0;
        for (int i = 1; i <= N; i++)
            scanf("%s", g[i] + 1);
    
        for (int i = N; i; i--) {
            for (int j = 1; j <= M; j++) {
                if (g[i][j] == '.') {
                    x[n] = i;
                    y[n] = j;
                    n++;
                }
            }
        }
    
        memset(c, 0, sizeof(c));
        for (int i = 0; i < n; i++)
            c[i] = judge(x[i], y[i], dir[0]);
    }
    
    /*
       int solve (int spi, int id) {
    
       memset(v, 0, sizeof(v));
       int ans = INF;
       for (int s = 0; s < (1<<n); s++) {
    
       bool flag = true;
       for (int i = 0; i < n; i++) {
       if (s&(1<<i) && (c[i] == 0 || i == spi)) {
       flag = false;
       break;
       }
       }
    
       if (flag) {
       int light = 0;
       int tmp = set(x[spi], y[spi], dir[id], 1);
    
       for (int i = 0; i < n; i++) {
       if (s&(1<<i)) {
       light++;
       tmp += set(x[i], y[i], dir[0], 1);
       }
       }
    
       if (tmp == n)
       ans = min(ans, light);
    
       memset(v, 0, sizeof(v));
       }
       }
       return ans+1;
       }
       */
    
    void dfs (int d, int f, int cnt) {
    
        if (cnt >= ans)
            return;
    
        if (d == n) {
            ans = cnt;
            return;
        }
    
        if (v[x[d]][y[d]])
            dfs (d + 1, f, cnt);
    
        if (c[d] && d != f) {
            set(x[d], y[d], dir[0], 1);
            dfs (d + 1, f, cnt+1);
            set(x[d], y[d], dir[0], 0);
        }
    }
    
    int main () {
        while (scanf("%d%d", &N, &M) == 2 && N + M) {
            init();
    
            ans = INF;
            if (n == 0)
                ans = 0;
    
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < 4; j++) {
                    if (judge (x[i], y[i], dir[j])) {
                        memset(v, 0, sizeof(v));
    
                        set(x[i], y[i], dir[j], 1);
    
                        dfs(0, i, 1);
    
                        set(x[i], y[i], dir[j], 0);
                    }
                }
            }
    
            if (ans == INF)
                printf("-1
    ");
            else
                printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    Windows上使用“LogView”打开大文件
    windows CMD命令查看局域网内所有主机名及IP
    解决Sqlserver 2008 R2在创建登录名出错"此版本的 Microsoft Windows 不支持 MUST_CHANGE 选项。 (Microsoft SQL Server,错误: 15195)"
    解决 ASP.NET 编辑错误"CS0006: 未能找到元数据文件C:WINDOWSassemblyGAC_32System.EnterpriseServices2.0.0.0__b03f5f7f11d50a3aSystem.EnterpriseServices.dll"
    ASP 未结束的字符串常量
    Godaddy ssl续费更新问题总结
    [转]How to query posts filtered by custom field values
    SqlServer 在查询结果中如何过滤掉重复数据
    [UE4]C++的const类成员函数
    [UE4]C++三种继承方式
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6731894.html
Copyright © 2011-2022 走看看