bjtu 1846. Infinity的装备[状压dp+dfs/bfs]
https://citel.bjtu.edu.cn/acm/oj/problem/1846
1846. Infinity的装备
时间限制 1000 ms
内存限制 64 MB
题目描述
“测试服终于下完了!” Infinity 来到了一望无际的沙漠 Miramar。
Infinity 降落到了 Los Leones 城,他在天上看到城区里有一些装备。
但是城区地形复杂、装备繁多,来回捡各种装备肯定要走不少回头路。
Infinity 想尽快搜齐所有装备,你能告诉他最快多久可以集齐所有装备吗?
Los Leones 城可以表示为一个 n×m
的矩形。
其中,
#
表示不可穿越的高墙,I
表示 Infinity 降落的位置,E
表示装备。
Infinity 一次移动可以向上下左右之一的方向移动一格,但不能到达高墙。
当 Infinity 和装备处于同一位置时,Infinity 可以(不消耗移动步数地)立即获得这个装备。
输入数据
第一行为一个整数 t (1≤t≤200)
,表示数据的组数。接下来对于每组数据:
第一行为三个整数 n,m,k (3≤n,m≤10;1≤k≤10)
,表示城市的高、宽,和装备的数量。
接下来 n
行,每行为一个长度为 m
的字符串,表示城市的布局,具体含义见题目描述。
保证城市的最外圈都是高墙。保证所有装备从初始位置可达。
输出数据
对于每组数据,输出一行:
第一行为一个整数,表示 Infinity 集齐所有装备所需最少的移动次数。
样例输入
1
5 7 2
#######
# I #
# ### #
# E#E #
#######
样例输出
14
样例说明
测试数据有点小问题,迷之 WA / RE / TLE 可以看一下这个链接。
http://blog.csdn.net/qwb492859377/article/details/48323443
[分析]:状压dp+dfs /网上搜一下这个有蛮多类似的题目.
[代码]:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define pb push_back
#define fi first
#define se second
#define ll long long
#define sz(x) (int)(x).size()
char a[][];
int id[][];
struct node{
int r,c;
};
int dp[<<][];
int sd[];
int ed[][];
vector<node> e;
int tmpd[][];
bool safe_gets(char *S){
int n = strlen(S);
if(!gets(S)) return false;
if(n && S[n - ] =='\r') S[n - ] = ;
return true;
}
int Lowbit(int x){
return x&(-x);
}
int xx[];
int main(){
int tmp=;
for(int i=;i<;i++){
xx[tmp]=i;
tmp*=;
}
int t;
scanf("%d",&t);
while(t--){
e.clear();
node s;
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
getchar();
getchar();
for(int i=;i<=n;i++){
safe_gets(a[i]+);
for(int j=;j<=m;j++){
if(a[i][j]=='E'){
id[i][j]=sz(e);
e.pb({i,j});
}else if(a[i][j]=='I'){
s={i,j};
}
}
}
if(sz(e)!=k)return ;
memset(tmpd,,sizeof(tmpd));
tmpd[s.r][s.c]=;
queue<pair<int,int>> q;
q.push({s.r,s.c});
while(q.size()){
int r=q.front().fi,c=q.front().se;
if(a[r][c]=='E'){
sd[id[r][c]]=tmpd[r][c];
}
q.pop();
if(a[r+][c]!='#' && tmpd[r+][c]==tmpd[][]){
tmpd[r+][c]=tmpd[r][c]+;
q.push({r+,c});
}
if(a[r][c+]!='#' && tmpd[r][c+]==tmpd[][]){
tmpd[r][c+]=tmpd[r][c]+;
q.push({r,c+});
}
if(a[r-][c]!='#' && tmpd[r-][c]==tmpd[][]){
tmpd[r-][c]=tmpd[r][c]+;
q.push({r-,c});
}
if(a[r][c-]!='#' && tmpd[r][c-]==tmpd[][]){
tmpd[r][c-]=tmpd[r][c]+;
q.push({r,c-});
}
}
for(int i=;i<sz(e);i++){
memset(tmpd,,sizeof(tmpd));
tmpd[e[i].r][e[i].c]=;
q.push({e[i].r,e[i].c});
while(q.size()){
int r=q.front().fi,c=q.front().se;
if(a[r][c]=='E'){
ed[i][id[r][c]]=tmpd[r][c];
}
q.pop();
if(a[r+][c]!='#' && tmpd[r+][c]==tmpd[][]){
tmpd[r+][c]=tmpd[r][c]+;
q.push({r+,c});
}
if(a[r][c+]!='#' && tmpd[r][c+]==tmpd[][]){
tmpd[r][c+]=tmpd[r][c]+;
q.push({r,c+});
}
if(a[r-][c]!='#' && tmpd[r-][c]==tmpd[][]){
tmpd[r-][c]=tmpd[r][c]+;
q.push({r-,c});
}
if(a[r][c-]!='#' && tmpd[r][c-]==tmpd[][]){
tmpd[r][c-]=tmpd[r][c]+;
q.push({r,c-});
}
}
}
int res=1e9;
memset(dp,,sizeof(dp));
for(int i=;i<k;i++){
dp[<<i][i]=sd[i];
if(k==)res=sd[i];
}
int up=(<<k);
for(int j=;j<=k;j++){
for(int mask = (<<j)-;mask<up;){
vector<int> out,in;
for(int i=;i<k;i++){
if(mask&(<<i)){
in.pb(i);
}
else out.pb(i);
}
for(int i=;i<sz(in);i++){
for(int j=;j<sz(out);j++){
dp[mask|(<<out[j])][out[j]]=min(dp[mask|(<<out[j])][out[j]],dp[mask][in[i]]+ed[in[i]][out[j]]);
}
}
int tmp=mask & -mask;
mask = (mask + tmp) | (((mask^(mask+tmp))>>)/tmp);
}
}
for(int i=;i<k;i++)res=min(dp[up-][i],res);
printf("%d\n",res);
}
return ;
}
bjtu 1846. Infinity的装备[状压dp+dfs/bfs]的更多相关文章
- HDU 4272 LianLianKan (状压DP+DFS)题解
思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...
- BZOJ-1087 互不侵犯King 状压DP+DFS预处理
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2337 Solved: 1366 [Submit][ ...
- 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)
洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...
- 【POJ 2411】【Mondriaans Dream】 状压dp+dfs枚举状态
题意: 给你一个高为h,宽为w的矩阵,你需要用1*2或者2*1的矩阵填充它 问你能有多少种填充方式 题解: 如果一个1*2的矩形横着放,那么两个位置都用二进制1来表示,如果是竖着放,那么会对下一层造成 ...
- 【题解】P3959 宝藏 - 状压dp / dfs剪枝
P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝 ...
- HDUOJ Clear All of Them I 状压DP
Clear All of Them I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 122768/62768 K (Java/Oth ...
- Codevs 2009 大dota英雄 2013年省队选拔赛辽宁(状压DP)
2009 大dota英雄 2013年省队选拔赛辽宁 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 话说退役后的生活好无聊啊,以 ...
- [状压DP]炮兵阵地
炮 兵 阵 地 炮兵阵地 炮兵阵地 题目描述 司令部的将军们打算在 N ∗ M N*M N∗M的网格地图上部署他们的炮兵部队.一个 N ∗ M N*M N∗M的地图由 N N N行 M M M列组成, ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
随机推荐
- linux下查找文件命令总结
主要有find,locate,whereis,which等 1. find是最常用也是最强大的查找命令,它可以查找任何类型的文件. find命令的一般格式为:find <指定目录>< ...
- 1、python的基础
一.python组成 python程序的内容主要由变量.数据.关键字.操作符组成. 二.变量 在python中,变量指的是其指向的数据是可变的. 首先我们要了解一下python的内存管理.数据创建后就 ...
- CCPC_1005
可怕.....的提.....显而易见的规律活活没照出来...不过说起来却是不能严格证明....于是...脑筋急转弯活活猜不出来..... 1*1->1*2->2*2->2*3-> ...
- [转载]C#中使用ADO.NET连接SQL Server数据库,自动增长字段用作主键,处理事务时的基本方法
问题描述: 假设在数据库中存在以下两张数据表: User表,存放用户的基本信息,基本结构如下所示: 类型 说明 ID_User int 自动增长字段,用作该表的主键 UserName varcha ...
- android静默安装和智能安装(转)
Android 静默安装和智能安装的实现方法 http://blog.csdn.net/fuchaosz/article/details/51852442 Android静默安装实现方案,仿360手机 ...
- vba中获取当前sheet页的名称,当前单元格所在位置
fname = ActiveSheet.Name-------获取当前sheet页的名称 Sname = "" & fname & "&qu ...
- 图学java基础篇之IO
java io体系 如图可以看出,java的io按照包来划分的话可以分为三大块:io.nio.aio,但是从使用角度来看,这三块其实揉杂在一起的,下边我们先来概述下这三块: io:主要包含字符流和字节 ...
- 重新安装Linux自带的JDK
1.卸载现有jdk 查看本机已经安装的JDK的版本: [root@mcb ~]# java -version java version "1.6.0" OpenJDK Runtim ...
- python 类中__init__,__new__,__class__的使用详解
1.python中所有类默认继承object类,而object类提供了很多原始的内置属性和方法,所有用户定义的类在python 中也会继承这些内置属性.我们可以通过dir()进行查看.虽然python ...
- sed处理大txt文件(1G) 比如替换某一串字符串,或者删除一行
1.将11.sql文件中"prompt"替换为"--prompt",然后保存为111.sql文件 sed -e "s,prompt,--prompt, ...