hdu 3682
来源:互联网 发布:c语言九九乘法编程 编辑:程序博客网 时间:2024/06/15 05:27
二分 + 状压dp
dp[i][j]表示终点为i,访问状态为j剩余的最大能量
二分一个上限能量
dp[i][j] 可以由dp[k][s]转移过来,表示从k点走到i点,如果k点是一个电池的话那么只要满足dp[k][s]剩余的能量 >= 0,否则则是dp[k][s] - dist[i][k]
#include <cstdio>#include <cstring>#include <queue>using namespace std;const int maxn = 30;const int INF = 10007;struct Point { int x, y, d;};int tot;struct Point point[maxn];int type[maxn], num[maxn][maxn];int dp[17][1 << (16)];int goal;int n, m;int step[4][2] = {{0, 1}, {0,-1},{-1, 0}, {1, 0}};char maps[maxn][maxn];queue<struct Point> que;int dist[maxn][maxn], vis[maxn][maxn];int pre[17][1 << 16];void bfs(int source) { memset(vis, 0, sizeof(vis)); for (int i = 0; i <= tot; i++) { dist[source][i] = INF; } memset(vis, 0, sizeof(vis)); dist[source][source] = 0; point[source].d = 0; que.push(point[source]); vis[point[source].x][point[source].y] = 1; while (!que.empty()) { struct Point p = que.front(); que.pop(); for (int k = 0; k < 4; k++) { int next_x = p.x + step[k][0]; int next_y = p.y + step[k][1]; if (next_x >= 0 && next_x < n && next_y >= 0 && next_y < m && !vis[next_x][next_y] && maps[next_x][next_y] != 'D') { vis[next_x][next_y] = 1; struct Point a; a.x = next_x; a.y = next_y; a.d = p.d + 1; if (num[next_x][next_y] != -1) { dist[source][num[next_x][next_y]] = p.d + 1; } que.push(a); } } }}bool check(int p) { memset(dp, -1, sizeof(dp)); dp[0][1] = p; for (int i = 1; i < (1 << tot); i++) { for (int j = 0; j < tot; j++) { if (!(i & (1 << j))) { continue; } for (int k = 0; k < tot; k++) { if (i & (1 << k) && k != j) { if (type[k] == 1) { if (dp[k][i ^ (1 << j)] < 0) { continue; } dp[j][i] = max(dp[j][i], p - dist[k][j]); } else { dp[j][i] = max(dp[j][i], dp[k][i ^ (1 << j)] - dist[k][j]); } } } if (((i & goal) == goal) && dp[j][i] >= 0) { return true; } } } return false;}int main() {// freopen("in.txt", "r", stdin); while (scanf("%d%d", &n, &m) != EOF) { if (!n && !m) { break; } for (int i = 0; i < n; i++) { scanf("%s", maps[i]); } tot = 1; goal = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { num[i][j] = -1; if (maps[i][j] == 'F') { point[0].x = i; point[0].y = j; num[i][j] = 0; } else if (maps[i][j] == 'G') { point[tot].x = i; point[tot].y = j; num[i][j] = tot; type[tot] = 1; tot++; } else if (maps[i][j] == 'Y') { point[tot].x = i; point[tot].y = j; type[tot] = 2; num[i][j] = tot; goal |= (1 << tot); tot++; } } } for (int i = 0; i < tot; i++) { bfs(i); } int flag = 0; for (int i = 1; i < tot; i++) { if (type[i] == 2 && dist[0][i] == INF) { flag = 1; break; } } if (flag) { puts("-1"); continue; } int low = 0; int high = INF; while (low <= high) { int mid = (low + high) >> 1; if (check(mid)) { high = mid - 1; } else { low = mid + 1; } } printf("%d\n", low); } return 0;}
0 0
- hdu 3682
- hdu 3682
- HDU 3682 水模拟
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- Servlet系列(二)----Servlet基础
- TopCoder—ZigZag
- POJ 1742 Coins(多重背包)
- java 1加到100
- XDOJ1170 - 蛋疼的游戏
- hdu 3682
- 在线分享Oracle尖峰时刻--2014年中秋节尖峰在线福利!
- dancing link 资料
- POJ 2063Investment(完全背包)
- Java开发中的23种设计模式详解
- 【BZOJ】【P2463】【中山市选2009】【题解】【谁能赢呢?】
- 使用crontab定时执行php
- HDU-3085-Nightmare Ⅱ(双向BFS)
- 杭电1279 Stone Game(经典博弈)