hdu4856(状态压缩)
来源:互联网 发布:剑三抓马坐标数据下载 编辑:程序博客网 时间:2024/05/01 15:16
题目:1010 Tunnels
链接: http://acm.h
题意:给定一个n*n的迷宫,迷宫有障碍物,然后给出一些在这个迷宫的地下通道(相当于传送门,进入入口就直接到出口),问走过所有通道一次,最少的时间消耗是多少
详细见样例吧!
思路:状态压缩+bfs,首先bfs求出所有通道的出口到所有通道的入口的最短距离。然后定义dp[i][j],表示最后一个走的通道是第i个,已经走过的通道是j里面二进制位是1的,
比如说dp[2][01011],此时的i是2,j是11(十进制),表示选了1 2 4 通道,而且第二通道是最后一个选的!这样就可以状态转移了,这里说的二进制第几位是从后面开始数的
dp[j][i] = min(dp[j][i], dp[k][i ^ (1 << (j - 1))] + dis[k][j]); 其中转移的时候要满足j不等于k,且i的二进制位的j和k位已经是1了。
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <iostream>using namespace std;#define N 20char s[N][N];const int inf = (1 << 25);int dp[20][1 << 15];int n, m;struct no{ int id, x1, y1, x2, y2;}e[N];int st[N][N];struct node{ int x, y, step;};bool vis[N][N];int dis[N][N];int dir[][2] = { 0, 1, 1, 0, 0, -1, -1, 0 };bool ok(int x, int y){ if (x >= 1 && x <= n && y > 0 && y <= n) return true; return false;}void BFS(int x, int y, int id){ queue<node> Q; node now, next; now.x = x; now.y = y; now.step = 0; Q.push(now); memset(vis, false, sizeof(vis)); vis[x][y] = true; while (!Q.empty()) { now = Q.front(); Q.pop(); if (st[now.x][now.y]) { for (int i = 1; i <= m; i++) if (now.x == e[i].x1 && now.y == e[i].y1) dis[id][e[i].id] = (id == e[i].id ? inf : now.step); } for (int i = 0; i < 4; i++) { next.x = now.x + dir[i][0]; next.y = now.y + dir[i][1]; next.step = now.step + 1; if (ok(next.x, next.y) && !vis[next.x][next.y] && s[next.x][next.y] != '#') { vis[next.x][next.y] = true; Q.push(next); } } }}int main(){ while (scanf("%d%d", &n, &m) != EOF) { for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1); memset(st, 0, sizeof(st)); for (int i = 1; i <= m; i++) { scanf("%d%d%d%d", &e[i].x1, &e[i].y1, &e[i].x2, &e[i].y2); st[e[i].x1][e[i].y1] = i; e[i].id = i; } for (int i = 1; i <= m; i++) for (int j = 1; j <= m; j++) dis[i][j] = inf; for (int i = 1; i <= m; i++)//bfs处理 { BFS(e[i].x2, e[i].y2, e[i].id); } for (int i = 0; i <= m; i++) { for (int j = 0; j < (1 << n); j++)dp[i][j] = inf; } for (int i = 1; i <= m; i++)dp[i][1 << (i - 1)] = 0;//开始选的时候任意,这个时候时间都是0 for (int i = 0; i < (1 << m); i++) { for (int j = 1; j <= m; j++) { for (int k = 1; k <= m; k++) { if (k == j)continue; if (((1 << (j - 1))&i) && ((1 << (k - 1))&i))//i的二进制位的j和k位已经是1了 dp[j][i] = min(dp[j][i], dp[k][i ^ (1 << (j - 1))] + dis[k][j]); } } } int res = inf; for (int i = 1; i <= m; i++)res = min(res, dp[i][(1 << m) - 1]); if (res >= inf)puts("-1"); else printf("%d\n", res); }}
0 0
- hdu4856(状态压缩)
- hdu4856(bfs + 状态压缩)
- 状态dp小结 (hdu4804 hdu4856 hdu3681 poj3311 hdu3001 cf453B hdu4906 zoj3802)
- hdu1885(状态压缩)
- poj3254(状态压缩)
- hdu1565(状态压缩)
- poj1185(状态压缩)
- 状态压缩(初识)
- HIHO #1044 : 状态压缩·一(状态压缩dp)
- 状态压缩(1)--hdu5094(状态压缩+bfs)(能力题)
- hdu1565(状态压缩dp)
- (状态压缩) Travelling (HDU3001)
- uva10160(dfs+状态压缩)
- hdu 4739(状态压缩)
- zoj 3471(状态压缩)
- 状态压缩DP(二)
- 状态压缩dp(hdu3406)
- Hdu 1429(状态压缩)
- 利用webservice查询ip的物理地址 java实现
- EL 表达式
- Android颜色(RGB)对照表
- 文本输入与输出
- hibernate抓取策略
- hdu4856(状态压缩)
- JNDI 是什么
- 抽象工厂模式
- MySQL存储引擎比较
- 找工作
- UVA 712 S-Trees
- Codeforces 50C Happy Farm 5 凸包
- 批处理中如何判断参数中含有某些字符串?
- Oracle内存管理(之五)