HDU 3681 Prison Break(状压DP + BFS)题解
题意:一张图,F是起点,Y是必须要到的点,D不能走,G可以充电。可以往四个方向走,每走一步花费一个电,走到G可以选择充满电或者不充,每个G只能充一次。问你走遍Y的最小初始点亮。number(G) + number(Y) <= 15
思路:显然Y和G都只要用一次就行,那么状压YG状态。然后BFS出任意YG两点最短路,状压DP。用&判断最终结果是不是当前状态的子集。
代码:
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 15;
const int M = maxn * 30;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1e4 + 7;
int dp[1 << maxn][maxn];
char mp[maxn + 10][maxn + 10];
int n, m, sx, sy;
int cnt;
int id[maxn * maxn + 20];
int bettery[maxn * maxn + 20];
int getid(int x, int y){
return id[x * m + y];
}
struct Node{
int x, y, step;
};
int dis[maxn * maxn + 10][maxn * maxn + 10];
int vis[maxn + 5][maxn + 5];
int to[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
void bfs(int x, int y){
memset(vis, 0, sizeof(vis));
Node a, b;
queue<Node> q;
while(!q.empty()) q.pop();
vis[x][y] = 1;
a.x = x, a.y = y, a.step = 0;
q.push(a);
while(!q.empty()){
a = q.front();
q.pop();
if(mp[a.x][a.y] != 'D' && mp[a.x][a.y] != 'S') dis[getid(x, y)][getid(a.x, a.y)] = a.step;
for(int i = 0; i < 4; i++){
b.x = a.x + to[i][0];
b.y = a.y + to[i][1];
if(b.x < 0 || b.y < 0 || b.x >= n || b.y >= m) continue;
if(vis[b.x][b.y]) continue;
if(mp[b.x][b.y] == 'D') continue;
vis[b.x][b.y] = 1;
b.step = a.step + 1;
q.push(b);
}
}
} int Fin;
bool check(int st){
memset(dp, -1, sizeof(dp));
for(int i = 0; i < cnt; i++){
if(dis[cnt][i] <= st){
if(bettery[i]) dp[1 << i][i] = st;
else dp[1 << i][i] = st - dis[cnt][i];
}
} for(int i = 0; i < (1 << cnt); i++){
for(int j = 0; j < cnt; j++){
if(dp[i][j] == -1) continue;
if(!((1 << j) & i)) continue;
if((i & Fin) == Fin) return true;
for(int k = 0; k < cnt; k++){
if((1 << k) & i) continue;
if(dis[j][k] > dp[i][j]) continue;
dp[i | (1 << k)][k] = max(dp[i][j] - dis[j][k], dp[i | (1 << k)][k]);
if(bettery[k]) dp[i | (1 << k)][k] = st;
}
}
} return false;
} int main(){
while(~scanf("%d%d", &n, &m) && n + m){
cnt = 0;
Fin = 0;
int tmp = 0;
memset(bettery, 0, sizeof(bettery));
for(int i = 0; i < n; i++){
scanf("%s", mp[i]);
for(int j = 0; j < m; j++){
if(mp[i][j] == 'F'){
sx = i, sy = j;
}
else if(mp[i][j] == 'G'){
bettery[cnt] = 1;
id[i * m + j] = cnt++;
}
else if(mp[i][j] == 'Y'){
Fin += (1 << cnt);
id[i * m + j] = cnt++;
tmp++;
}
}
}
id[sx * m + sy] = cnt; if(tmp == 0){
printf("0\n");
continue;
} memset(dis, INF, sizeof(dis));
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(mp[i][j] != 'D' && mp[i][j] != 'S')
bfs(i, j);
}
} int l = 0, r = 1000000;
int ans = -1;
while(l <= r){
int m = (l + r) >> 1;
if(check(m)){
r = m - 1;
ans = m;
}
else l = m + 1;
}
printf("%d\n", ans);
}
return 0;
}
HDU 3681 Prison Break(状压DP + BFS)题解的更多相关文章
- hdu 3247 AC自动+状压dp+bfs处理
Resource Archiver Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Ot ...
- HDU 4272 LianLianKan(状压DP)题解
题意:一个栈,每次可以选择和栈顶一样的数字,并且和栈顶距离小于6,然后同时消去他们,问能不能把所有的数消去 思路:一个数字最远能消去和他相距9的数,因为中间4个可以被他上面的消去.因为还要判断栈顶有没 ...
- HDU 4628 Pieces(状压DP)题解
题意:n个字母,每次可以删掉一组非连续回文,问你最少删几次 思路:把所有回文找出来,然后状压DP 代码: #include<set> #include<map> #includ ...
- hdu 2825 aC自动机+状压dp
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS
BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS Description Farmer John has taken the cows to a va ...
- HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解
题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...
- HDU 5765 Bonds(状压DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不 ...
- hdu 4778 Gems Fight! 状压dp
转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...
- HDU 4272 LianLianKan (状压DP+DFS)题解
思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...
随机推荐
- CTO也糊涂的常用术语:功能模块、业务架构、用户需求、文档……
功能模块.业务架构.需求分析.用户需求.系统分析.功能设计.详细设计.文档.业务.技术--很多被随口使用的名词,其实是含糊甚至错误的. 到底含糊在哪里,错误在哪里,不仅仅是新手软件开发人员糊涂,许多入 ...
- Let’s Encrypt/Certbot移除/remove/revoke不需要的域名证书
1.首先确认你的证书不再需要,如果有必要,请执行下面的命令进行备份 cp /etc/letsencrypt/ /etc/letsencrypt.backup -r 2.撤销证书然后删除证书 [root ...
- postgres多知识点综合案例
使用到的知识点: 1.使用with临时存储sql语句,格式[with as xxx(), as xxx2() ]以减少代码: 2.使用round()取小数点后几位: 3.使用to_char()将时间格 ...
- Property or method "previewUrl" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components,
Property or method "previewUrl" is not defined on the instance but referenced during rende ...
- Python的交互模式和直接运行.py文件有什么区别
使用文本编辑器 - 廖雪峰的官方网站 https://www.liaoxuefeng.com/wiki/1016959663602400/1017024645952992 直接输入python进入交互 ...
- hadoop 集群搭建 配置 spark yarn 对效率的提升永无止境 Hadoop Volume 配置
[手动验证:任意2个节点间是否实现 双向 ssh免密登录] 弄懂通信原理和集群的容错性 任意2个节点间实现双向 ssh免密登录,默认在~目录下 [实现上步后,在其中任一节点安装\配置hadoop后,可 ...
- 从零开始学Java (三)基础语法
1. 基本数据类型 整数类型:byte,short,int,long 浮点数类型:float,double 字符类型:char 布尔类型:boolean java最小单位是bit,一个byte占用8个 ...
- SpringBoot+Spring常用注解总结
为什么要写这篇文章? 最近看到网上有一篇关于 SpringBoot 常用注解的文章被转载的比较多,我看了文章内容之后属实觉得质量有点低,并且有点会误导没有太多实际使用经验的人(这些人又占据了大多数). ...
- 【译】Async/Await(四)—— Pinning
原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...
- HTML5 学习表格应用
<table> <tr> ---tr 定义行 <td>第1个单元格的内容</td> ----td 定义列 <td>第2个单元格的内容< ...