HDU - 5067 Harry And Dig Machine (bfs + 状态压缩)
来源:互联网 发布:农村淘宝黄岩服务中心 编辑:程序博客网 时间:2024/05/21 20:44
题目大意:有一个n*m的网格,网格上面有k个地方有石头,现在要求从左上角出发,遍历所有有石头的地方,然后回到左上角,问最短距离是多少
解题思路:因为石头的总数小于等于10,所以可以进行压缩
设dp[i][j][state]表示在(i,j)位置,遍历的石头状态为state,走的最小距离,直接bfs即可
#include <cstdio>#include <cstring>#include <algorithm>#include <map>#include <queue>using namespace std;#define N 55#define S (1<<11)#define INF 0x3f3f3f3fstruct Node { int x, y, state, step;}start;map<int, int> M;int n, m, stone_num;int dp[N][N][S], g[N][N];int dir[4][2] = {{-1,0}, {1,0}, {0, -1}, {0,1}};void init() { M.clear(); stone_num = 0; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) { scanf("%d", &g[i][j]); if (g[i][j]) M[i * m + j] = stone_num++; } memset(dp, 0, sizeof(dp));}int bfs() { queue<Node> q; start.x = 0; start.y = 0; if (g[0][0]) start.state = (1 << M[0]); else start.state = 0; start.step = 0; q.push(start); while (!q.empty()) { Node t = q.front(); q.pop(); int x = t.x, y = t.y; if (x == 0 && y == 0 && t.state == (1 << stone_num) - 1) { break; } for (int i = 0; i < 4; i++) { int xx = x + dir[i][0]; int yy = y + dir[i][1]; int state = t.state; int step = t.step; if (xx < 0 || yy < 0 || xx >= n || yy >= m ) continue; if (g[xx][yy]) state |= (1 << M[xx * m + yy]); if (dp[xx][yy][state]) continue; dp[xx][yy][state] = step + 1; Node tt; tt.x = xx; tt.y = yy; tt.state = state; tt.step = t.step + 1; q.push(tt); } } return dp[0][0][(1 << stone_num) - 1];}int main() { while (scanf("%d%d", &n, &m) != EOF) { init(); if(stone_num == 0) printf("0\n"); else printf("%d\n", bfs()); } return 0;}
上面是我复杂化了,其实只是状态压缩而已,只需要计算一下每种状态的转移就可以了,不需要一格格的走。。。
#include <cstdio>#include <cstring>#include <cstdlib>#include <queue>using namespace std;#define S (1 << 11)#define N 20#define INF 0x3f3f3f3fstruct Stone { int x, y;}stone[N];struct Node { int state, pos;}start;int n, m;int dp[S][N], cnt;void init() { int x; cnt = 1; stone[0].x = 0; stone[0].y = 0; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) { scanf("%d", &x); if(x) { stone[cnt].x = i; stone[cnt++].y = j; } }}int dis(int i, int j) { return abs(stone[i].x - stone[j].x) + abs(stone[i].y - stone[j].y);}void solve() { memset(dp, 0x3f, sizeof(dp)); queue<Node> q; start.state = 1; start.pos = 0; q.push(start); dp[1][0] = 0; while (!q.empty()) { Node t = q.front(); q.pop(); int state = t.state; int pos = t.pos; for (int i = 1; i < cnt; i++) { if (!(state & (1 << i))) { if ((state | (1 << i)) == (1 << cnt) - 1) { dp[state | (1 << i)][i] = min(dp[state | (1 << i)][i], dp[state][pos] + dis(pos,i) + dis(0,i)); } else { if(dp[state | (1 << i)][i] > dp[state][pos] + dis(pos, i)) { dp[state | (1 << i)][i] = dp[state][pos] + dis(pos, i); Node tt; tt.state = state | (1 << i); tt.pos = i; q.push(tt); } } } } } int ans = INF; for(int i = 1; i < cnt; i++) ans = min(ans, dp[(1 << cnt) - 1][i]); printf("%d\n", ans);}int main() { while(scanf("%d%d", &n, &m) != EOF) { init(); if(cnt == 1) printf("0\n"); else solve(); } return 0;}
0 0
- HDU - 5067 Harry And Dig Machine (bfs + 状态压缩)
- hdu 5067 Harry And Dig Machine(状态压缩dp)
- HDU 5067 Harry And Dig Machine 状态压缩 DP
- hdu 5067 Harry And Dig Machine (状态压缩dp)
- HDOJ 5067Harry And Dig Machine(状态压缩DP)
- hdu 5067 Harry And Dig Machine
- hdu 5067 Harry And Dig Machine
- HDU 5067 Harry And Dig Machine
- HDU 5067 Harry And Dig Machine
- hdu 5067 Harry And Dig Machine
- hdu 5067 Harry And Dig Machine(dp)
- hdu 5067 Harry And Dig Machine
- HDU 5067 Harry And Dig Machine (DFS)
- HDU 5067Harry And Dig Machine(暴力)
- HDU 5067 Harry And Dig Machine
- HDU 5067 Harry And Dig Machine
- HDU 5067 Harry And Dig Machine(状压dp)
- HDU 5067-Harry And Dig Machine(DFS)
- Linux Samba 安装及配置
- Model绑定机制1:简单类型+复杂类型
- Java中方法的重载
- 关于tomcat+MyEclipse的安装与配置
- POJ 2409-Let it Bead(Polya计数)
- HDU - 5067 Harry And Dig Machine (bfs + 状态压缩)
- string 简单实现
- IOS 界面传值
- jvm内存使用上限
- Model绑定机制2:数组
- Linux: /dev/random , /dev/urandom
- hdu5289 2015多校联合第一场1002 Assignment
- 连接查询,条件在on和where后面的区别
- 使用Profiler工具分析内存占用情况