Problem Description

小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫。因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷宫。

 Input

有多组测试数据。

每组数据第一行给出两个正整数n,m(0<n,m<=100)。代表迷宫的长和宽。

接着n行,每行m个整数。正数代表财宝(财宝的个数不超过10);负数代表墙,无法通过;0代表通道。

每次移动到相邻的格子,所花费的时间是1秒。小明只能按上、下、左、右四个方向移动。

小明的初始位置是(1,1)。迷宫的出口也在(1,1)。

 Output

输出获得所有财宝并逃出迷宫所花费的最小时间,如果无法完成目标则输出-1。

 Sample Input

3 3 0 0 0 0 100 0 0 0 0 2 2 1 1 1 1

 Sample Output

4 4
 
思路: 发现是一个中国邮递员问题,果断压状
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<queue>
  5. using namespace std;
  6. const int dx[]={,,,,-},dy[]={,,-,,};
  7. int a[][],monx[],mony[],n,m,ma[][];
  8. queue<int>qans,qx,qy;
  9. bool visit[][];
  10. int check(int x,int y){
  11. if(x<= || x>n || y<= || y>m || a[x][y]< || visit[x][y])return ;
  12. return ;
  13. }
  14. void bfs(int x,int y,int sc)
  15. {
  16. memset(visit,,sizeof(visit));
  17. int l=,r=;visit[x][y]=;
  18. qx.push(x);qy.push(y);qans.push();
  19. while(!qx.empty())
  20. {
  21. x=qx.front();y=qy.front();
  22. qx.pop();qy.pop();
  23. int ans=qans.front();
  24. qans.pop();
  25. for(int i=;i<=;i++)
  26. {
  27. int xx=x+dx[i],yy=y+dy[i];
  28. if(check(xx,yy))continue;
  29. if(a[xx][yy]>)ma[sc][a[xx][yy]]=ans+;
  30. visit[xx][yy]=;
  31. qx.push(xx);qy.push(yy);qans.push(ans+);
  32. }
  33. }
  34. }
  35. int only_one(int k){
  36. if(k-(k & (-k)) == )return ;return ;
  37. }
  38. int dp[][];
  39. int dfs2(int k,int s,int h)
  40. {
  41. if(dp[k][s]!=-)return dp[k][s];
  42. if(only_one(s))return ma[k][];
  43. int ans=0x3f3f3f3f,full = ((<<(h))-) ^ (<<(k-));
  44. for(int i=;i<=h;i++)
  45. if(i != k && ((s & ((<<(i-)))) !=))ans=min(ans,dfs2(i,s & full,h) + ma[k][i]);
  46. return dp[k][s]=ans;
  47. }
  48. int main()
  49. {
  50. while(scanf("%d%d",&n,&m)!=EOF)
  51. {
  52. memset(dp,-,sizeof(dp));
  53. memset(ma,0x3f,sizeof(ma));
  54. int h=,flag=;
  55. for(int i=;i<=n;i++)
  56. {
  57. for(int j=;j<=m;j++)
  58. {
  59. scanf("%d",&a[i][j]);
  60. if(i== && j==)flag=a[i][j];
  61. if(a[i][j]> || (i== && j==))a[i][j]=++h,monx[h]=i,mony[h]=j;
  62. }
  63. }
  64. for(int i=;i<=h;i++)ma[i][i]=;
  65. for(int i=;i<=h;i++)bfs(monx[i],mony[i],i);
  66. if(flag<)
  67. {
  68. printf("-1\n");continue;
  69. }
  70. int u=dfs2(,(<<h)-,h);
  71. if(u>=0x3f3f3f3f)u=-;
  72. printf("%d\n",u);
  73. }
  74. return ;
  75. }

FZU 2186 小明的迷宫 【压状dp】的更多相关文章

  1. HDU 4521 小明系列问题——小明序列 (线段树维护DP)

    题目地址:HDU 4521 基本思路是DP.找前面数的最大值时能够用线段树来维护节省时间. 因为间隔要大于d. 所以能够用一个队列来延迟更新,来保证每次询问到的都是d个之前的. 代码例如以下: #in ...

  2. 【bzoj2064】分裂【压状dp】

    Description 背景: 和久必分,分久必和... 题目描述: 中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力. 同时经常搞OI的他把这个变成了一个数学模型. 假设中 ...

  3. C - 小明系列故事――捉迷藏 HDU - 4528 bfs +状压 旅游-- 最短路+状压

    C - 小明系列故事――捉迷藏 HDU - 4528 这个题目看了一下题解,感觉没有很难,应该是可以自己敲出来的,感觉自己好蠢... 这个是一个bfs 用bfs就很好写了,首先可以预处理出大明和二明能 ...

  4. hdu 4521 小明系列问题——小明序列 线段树+二分

    小明系列问题——小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Pro ...

  5. HDU4528 小明捉迷藏 [搜索-BFS]

    一.题意 小明S在迷宫n*m中找大明D和二明E,障碍物X不能走,问你计算是否能在时间t内找到大明和二明 二.分析 2.1与普通的BFS不同,这里可以走回头路,这里应该建立四维的标记数组标记数组,例如v ...

  6. HDU 4336 Card Collector(状压 + 概率DP 期望)题解

    题意:每包干脆面可能开出卡或者什么都没有,一共n种卡,每种卡每包爆率pi,问收齐n种卡的期望 思路:期望求解公式为:$E(x) = \sum_{i=1}^{k}pi * xi + (1 - \sum_ ...

  7. 小明的密码-初级DP解法

    #include #include #include using namespace std; int visited[5][20][9009];// 访问情况 int dp[5][20][9009] ...

  8. 小明系列问题――小明序列(LIS)

    小明系列问题――小明序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  9. ACM 擅长排列的小明

    擅长排列的小明 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 小明十分聪明,而且十分擅长排列计算.比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想 ...

随机推荐

  1. 异步 BeginInvoke

    委托的异步调用异步多线程的三大特点:1.同步方法卡界面,原因是主线程被占用:异步方法不卡界面,原因是计算交给了别的线程,主线程空闲2.同步方法慢,原因是只有一个线程计算:异步方法快,原因是多个线程同事 ...

  2. POJ 1655 Balancing Act (树的重心,常规)

    题意:求树的重心,若有多个重心,则输出编号较小者,及其子树中节点最多的数量. 思路: 树的重心:指的是一个点v,在删除点v后,其子树的节点数分别为:u1,u2....,设max(u)为其中的最大值,点 ...

  3. 51nod 1283 最小周长

    一个矩形的面积为S,已知该矩形的边长都是整数,求所有满足条件的矩形中,周长的最小值.例如:S = 24,那么有{1 24} {2 12} {3 8} {4 6}这4种矩形,其中{4 6}的周长最小,为 ...

  4. PHP开发基础视频教程

    PHP现今作为互联网运用很广泛的编程语言,市场需求量也越来越高,而PHP开发工程师的薪资也是一路水涨船高,更多的人看到了PHP的发展前景,纷纷都想投入到PHP的开发大军中来,那么对于很多转行或者零基础 ...

  5. ActiveMQ消息丢失怎么解决?

    在消息发送过程中消息丢失的话该怎么解决(包括网络原因): 解决思路: 可以把消息唯一ID,存到表里面,当消息接受端可以获取到这个ID,就给服务端一个回复IF,消息发送出去,没有回复,THEN一直循环发 ...

  6. make与makefile的几个例子和(自己写一下,汗!忘记了!)总结

    共用的几个源代码文件: main.c 2.c 3.c 代码依次为: #include<stdlib.h> #include "a.h" extern void func ...

  7. (转)MyBatis框架的学习(五)——一对一关联映射和一对多关联映射

    http://blog.csdn.net/yerenyuan_pku/article/details/71894172 在实际开发中我们不可能只是对单表进行操作,必然要操作多表,本文就来讲解多表操作中 ...

  8. v-if与v-show的区别与选择

      v-if与v-show的区别与选择 官网给的区别 v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建. v-if也是惰性的:如果在初始渲染时条件 ...

  9. 项目中多条数据保存的json实例

    //js代码function checkCode(num){ var typeid = $("#typeid").val(); if(typeid == "") ...

  10. 初识 Hibernate

    Hibernate 框架 1.1   什么是框架? 框架是一个提供了可重用的公共结构半成品. 2.1   关于Hibernate Hibernate是数据持久层的一个轻量级框架.数据持久层的框架有很多 ...