题目:https://www.luogu.org/problemnew/show/P1979

感到无从下手。但不妨用dp的角度来看。因为空格只有在指定棋子的旁边才有用,所以状态记成制定棋子的位置与空格在自己的哪侧。

转移有两种:与空格交换位置 或 让空格换一个方向。为了第二个转移,需要预处理,bfs出指定棋子在 (x,y) 时从它的哪边走到哪边的最短路。

dp的转移可以套到最短路里做。一开始需要让空格来到指定棋子的四个方向(bfs)。然后多源最短路或者做4遍最短路。

别忘了优先队列自然的就是从大到小排列的!!!

自己的写法需要特判走0步的情况。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<queue>
  6. using namespace std;
  7. const int N=,K=,M=N*N,INF=0x3f3f3f3f-;
  8. int n,m,Q,f[N][N][K][K],dis[N][N],dp[N][N][K];
  9. int he,tl,xx[K]={-,,,},yy[K]={,-,,};
  10. int ex,ey,sx,sy,Tx,Ty,ans,tmp;
  11. bool b[N][N],vis[N][N][K];
  12. struct Node{
  13. int x,y,p,dis;
  14. Node(int x=,int y=,int a=,int d=):x(x),y(y),p(a),dis(d) {}
  15. bool operator< (const Node &b) const
  16. {return dis>b.dis;}//>!!!
  17. }q[M];
  18. priority_queue<Node> qu;
  19. void bfs(int x1,int y1,int x2,int y2)
  20. {
  21. he=tl=; int tx,ty;
  22. q[++tl]=Node(x1,y1,,);
  23. memset(dis,0x3f,sizeof dis);
  24. dis[x1][y1]=;
  25. while(he<tl)
  26. {
  27. Node k=q[++he];
  28. for(int i=;i<=;i++)
  29. {
  30. tx=k.x+xx[i]; ty=k.y+yy[i];
  31. if(!b[tx][ty])continue;
  32. if(dis[tx][ty]>INF)
  33. {
  34. dis[tx][ty]=dis[k.x][k.y]+;
  35. q[++tl]=Node(tx,ty,,);
  36. if(tx==x2&&ty==y2)return;
  37. }
  38. }
  39. }
  40. }
  41. void init()
  42. {
  43. memset(f,0x3f,sizeof f);
  44. for(int i=;i<=n;i++)
  45. for(int j=;j<=m;j++) if(b[i][j])
  46. for(int p0=;p0<=;p0++)
  47. for(int p1=p0+,x1,y1,x2,y2;p1<=;p1++)
  48. {
  49. x1=i+xx[p0]; y1=j+yy[p0];
  50. x2=i+xx[p1]; y2=j+yy[p1];
  51. if(!b[x1][y1]||!b[x2][y2]) continue;
  52. b[i][j]=;
  53. bfs(x1,y1,x2,y2);
  54. f[i][j][p0][p1]=f[i][j][p1][p0]
  55. =dis[x2][y2];
  56. b[i][j]=;
  57. }
  58. }
  59. void solve(int yp)
  60. {
  61. while(qu.size())qu.pop();
  62. qu.push(Node(sx,sy,yp,));
  63. memset(dp,0x3f,sizeof dp); dp[sx][sy][yp]=;//
  64. memset(vis,,sizeof vis);
  65. while(qu.size())
  66. {
  67. Node k=qu.top(); qu.pop();
  68. if(vis[k.x][k.y][k.p])continue;
  69. vis[k.x][k.y][k.p]=;
  70. if(k.x==Tx&&k.y==Ty)return;
  71. int tp=-k.p,tx=k.x+xx[k.p],ty=k.y+yy[k.p];
  72. if(dp[tx][ty][tp]>dp[k.x][k.y][k.p]+)
  73. {
  74. dp[tx][ty][tp]=dp[k.x][k.y][k.p]+;
  75. qu.push(Node(tx,ty,tp,dp[tx][ty][tp]));
  76. }
  77. tx=k.x; ty=k.y; tp=k.p;
  78. for(int i=;i<=;i++)
  79. {
  80. if(i==tp)continue;
  81. if(f[tx][ty][tp][i]<INF&&
  82. dp[tx][ty][i]>dp[tx][ty][tp]+f[tx][ty][tp][i])
  83. {
  84. dp[tx][ty][i]=dp[tx][ty][tp]+f[tx][ty][tp][i];
  85. qu.push(Node(tx,ty,i,dp[tx][ty][i]));
  86. }
  87. }
  88. }
  89. }
  90. int main()
  91. {
  92. scanf("%d%d%d",&n,&m,&Q);
  93. for(int i=;i<=n;i++)
  94. for(int j=,d;j<=m;j++)
  95. scanf("%d",&d),b[i][j]=d;
  96. init();
  97. he=tl=;
  98. while(Q--)
  99. {
  100. scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&Tx,&Ty);
  101. if(sx==Tx&&sy==Ty)
  102. {
  103. printf("0\n"); continue;
  104. }
  105. ans=INF+;
  106. for(int i=,tx,ty;i<=;i++)
  107. {
  108. tx=sx+xx[i]; ty=sy+yy[i];
  109. if(!b[tx][ty])continue;
  110. b[sx][sy]=;
  111. bfs(ex,ey,tx,ty);
  112. b[sx][sy]=;
  113. tmp=dis[tx][ty];
  114. if(tmp>INF)continue;
  115. solve(i);
  116. ans=min(ans,tmp+min(min(dp[Tx][Ty][],dp[Tx][Ty][]),
  117. min(dp[Tx][Ty][],dp[Tx][Ty][])));
  118. }
  119. printf("%d\n",ans>INF?-:ans);
  120. }
  121. return ;
  122. }

洛谷 1979 华容道——最短路+dp的更多相关文章

  1. 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)

    洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\)​​​​​.我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...

  2. 洛谷 P1979 华容道 解题报告

    P1979 华容道 题目描述 小\(B\)最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时 ...

  3. 洛谷2344 奶牛抗议(DP+BIT+离散化)

    洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...

  4. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  5. 洛谷P1541 乌龟棋(四维DP)

    To 洛谷.1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游 ...

  6. 【洛谷】P1052 过河【DP+路径压缩】

    P1052 过河 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙 ...

  7. 【题解】洛谷P1052 [NOIP2005TG] 过河(DP+离散化)

    题目来源:洛谷P1052 思路 一开始觉得是贪心 但是仔细一想不对 是DP 再仔细一看数据不对 有点大 如果直接存下的话 显然会炸 那么就需要考虑离散化 因为一步最大跳10格 那么我们考虑从1到10都 ...

  8. 洛谷1736(二维dp+预处理)

    洛谷1387的进阶版,但很像. 1387要求是“全为1的正方形”,取dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1]))吧?这个有“只有对 ...

  9. 【洛谷4933】大师(DP)

    题目: 洛谷4933 分析: (自己瞎yy的DP方程竟然1A了,写篇博客庆祝一下) (以及特斯拉电塔是向Red Alert致敬吗233) 这里只讨论公差不小于\(0\)的情况,小于\(0\)的情况进行 ...

随机推荐

  1. Bootstrap学习速查表(一) 理论基础

    参考网站http://www.bootcss.com/ 第一步,起步,引入基本样式 <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="st ...

  2. UbuntuServer12.04安装MongoDB,开机自启,服务,权限

    获取最新版本 去http://www.mongodb.org/downloads找最新版的链接 wget http://fastdl.mongodb.org/linux/mongodb-linux-x ...

  3. 小鬼PSer

    我是小鬼PSer,主要修图和做网站的,有需要可以call QQ:1805843351 微信:1805843351

  4. CocoaPods Podfile详解与使用

    1.为什么需要CocoaPods 在进行iOS开发的时候,总免不了使用第三方的开源库,比如SBJson.AFNetworking.Reachability等等.使用这些库的时候通常需要: 下载开源库的 ...

  5. 在ios中使用单例模式编程

    本文转载至 http://blog.csdn.net/remote_roamer/article/details/7107007     1.    @implementation Singleton ...

  6. Java 基础系列之volatile变量(一)

    一.锁 两种特性:互斥性(mutual exclusion).可见性(visibility).原子性(atomic) 互斥性就是一次只有一个线程可以访问该共享数据,可见性就是释放锁之前,对共享数据的修 ...

  7. Selenium 我的自动化测试历程 (Selenium+TestNG+Java+ReportNG+Jenkins)

    测试环境:Java+Selenium+TestNG,Jenkins持续集成. 测试代码 代码结构 采用页面对象模型(Page Object),减少UI修改后,对代码的影响.   Java编写,采用Te ...

  8. 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

  9. iOS 蓝牙开发之(mutipeerConnectivity)

    蓝牙 mutipeerConnectivity iOS7 引入的一个全新框架 替代GameKit框架 多用于文件传输 iOS设备不联网也能给附近的人聊天 搜索和传输的方式 * 双方WIFI和蓝牙都没有 ...

  10. php总结4——数组的定义及函数、冒泡排序

    4.1 数组的定义 数组:变量存储的有序序列. 索引数组:下标为数字的数组.  $数组名称(下标)    下标从0开始的数字. 直接定义: $arr[0]=123; $arr[1]="chi ...