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][ ...
随机推荐
- android shape.xml 文件使用
设置背景色可以通过在res/drawable里定义一个xml,如下: <?xml version="1.0" encoding="utf-8"?> ...
- activity切换交互动画
activity切换的时候,想要有动画,那么... 1.想要有效果的activity设置theme <activity android:name=".MainActivity" ...
- 浅谈I/O模型
在学习线程,NIO等知识时都需要知道一些基础知识. 一.什么是同步或异步 同步:个人通俗理解多个人排队打饭一个窗口,只有前面一个人打完了,后面的人才能打.如果前面人因为什么原因一直站在那里不走,后面的 ...
- loj2052 「HNOI2016」矿区
学习一发平面图的姿势--ref #include <algorithm> #include <iostream> #include <cstdio> #includ ...
- Uncaught TypeError: Cannot read property of undefined In JavaScript
当脚本遇到未初始化的变量或对象时,通常会抛出如上图所示的错误. Decription 'Undefined'是全局对象的属性.如果没有为变量赋值,则为'undefined'类型.当求值变量没有任何赋值 ...
- python 笔试总结
1.对比两种函数对应结果 def fn(x): if x>0: print(x) fn(x-1) ****结果****** 3 2 1 $$$$$$另外一种$$$$$$$$$ def fn(x) ...
- 一个 Observation
$n$ 个小球分布在一个圆上,小球的颜色或黑或白.顺时针(或逆时针)遍历这 $n$ 个小球,记录下相邻两小球的颜色,得到 $n$ 个有序颜色对.我们有,(黑,白)和(白,黑)的数目一定相等(可能都是 ...
- 微信小程序微信支付流程
1.小程序调用wx.login获取登录凭证code wx.login(无请求参数)返回code(有效期5分钟) wx.login({ success:function(res){ //get res. ...
- 【VBA】Do While……Loop循环,遍历某列
[说明] Do While……Loop循环,遍历某列 i = Do While Trim(T_sh.Cells(i, NOTESID_COL)) <> "" If T_ ...
- g2o安装
1.安装依赖项 sudo apt-get install libeigen3-dev libsuitesparse-dev libqt4-dev qt4-qmake 2.安装依赖项 libqglvi ...