题目描述

给出一个n*m的矩阵,某些格子不能通过,某些格子只能上下通过或左右通过。求经过所有非不能通过格子的哈密顿回路条数。

输入

第一行有两个数N, M表示地图被分割成N*M个块,接下来有N行,每行有M个字符。
 .  表示这个块可以通过
 - 表示这个块只可以左右通过
 | 表示这个块只可以上下通过
 # 表示这个块不能通过
(从每个块只能走到其上下左右相邻的四个块)

输出

一个数,表示小明把所以可以通过的块都经过且只经过一次并回到原地的方案数。

样例输入

4 4
....
..-.
....
....

样例输出

1


题解

插头dp

这道题 的唯一差别在于:部分格子只能上下通过或只能左右通过。

因此判断条件那里改一改就好了。

这里学了一下 CQzhangyu 的技♂巧:判断时只需要判断当前状态是否适用于当前格子,以及转移是否适用于当前格子即可。这样不合法的状态就会在下一步剪掉。这一步可以省很大的代码量。

注意开long long(题面的long指的就是int)

  1. #include <cstdio>
  2. #include <cstring>
  3. typedef long long ll;
  4. int m , a[13][13] , b[13] , w[1600000] , v[42000] , tot;
  5. ll f[13][13][42000];
  6. char str[14];
  7. void dfs(int p , int c , int now)
  8. {
  9. if(c < 0 || c > m - p + 1) return;
  10. if(p > m)
  11. {
  12. w[now] = ++tot , v[tot] = now;
  13. return;
  14. }
  15. dfs(p + 1 , c , now);
  16. dfs(p + 1 , c + 1 , now + b[p]);
  17. dfs(p + 1 , c - 1 , now + 2 * b[p]);
  18. }
  19. inline int l(int v , int p)
  20. {
  21. int i , c = 0;
  22. for(i = p ; ~i ; i -- )
  23. {
  24. if(v / b[i] % 3 == 1) c -- ;
  25. if(v / b[i] % 3 == 2) c ++ ;
  26. if(!c) return i;
  27. }
  28. return -1;
  29. }
  30. inline int r(int v , int p)
  31. {
  32. int i , c = 0;
  33. for(i = p ; i <= m ; i ++ )
  34. {
  35. if(v / b[i] % 3 == 1) c ++ ;
  36. if(v / b[i] % 3 == 2) c -- ;
  37. if(!c) return i;
  38. }
  39. return -1;
  40. }
  41. int main()
  42. {
  43. int n , i , j , k , x , y , p , q;
  44. ll ans = 0;
  45. scanf("%d%d" , &n , &m);
  46. for(i = 1 ; i <= n ; i ++ )
  47. {
  48. scanf("%s" , str + 1);
  49. for(j = 1 ; j <= m ; j ++ )
  50. {
  51. if(str[j] == '.' || str[j] == '-') a[i][j] |= 1;
  52. if(str[j] == '.' || str[j] == '|') a[i][j] |= 2;
  53. if(str[j] != '#') x = i , y = j;
  54. }
  55. }
  56. b[0] = 1;
  57. for(i = 1 ; i <= m ; i ++ ) b[i] = b[i - 1] * 3;
  58. dfs(0 , 0 , 0);
  59. f[0][m][w[0]] = 1;
  60. for(i = 1 ; i <= n ; i ++ )
  61. {
  62. for(j = 1 ; j <= tot ; j ++ )
  63. if(v[j] % 3 == 0)
  64. f[i][0][j] = f[i - 1][m][w[v[j] / 3]];
  65. for(j = 1 ; j <= m ; j ++ )
  66. {
  67. for(k = 1 ; k <= tot ; k ++ )
  68. {
  69. p = v[k] / b[j - 1] % 3 , q = v[k] / b[j] % 3;
  70. if((p && !(a[i][j] & 1)) || (q && !(a[i][j] & 2))) continue;
  71. if(!a[i][j]) f[i][j][k] += f[i][j - 1][k];
  72. else
  73. {
  74. if(!p && !q && a[i][j] == 3) f[i][j][w[v[k] + b[j - 1] + 2 * b[j]]] += f[i][j - 1][k];
  75. if(!p && q && a[i][j] & 1) f[i][j][k] += f[i][j - 1][k];
  76. if(p && !q && a[i][j] & 2) f[i][j][k] += f[i][j - 1][k];
  77. if(!p && q) f[i][j][w[v[k] + q * (b[j - 1] - b[j])]] += f[i][j - 1][k];
  78. if(p && !q) f[i][j][w[v[k] + p * (b[j] - b[j - 1])]] += f[i][j - 1][k];
  79. if(p == 1 && q == 1) f[i][j][w[v[k] - b[j - 1] - b[j] - b[r(v[k] , j)]]] += f[i][j - 1][k];
  80. if(p == 2 && q == 2) f[i][j][w[v[k] - 2 * (b[j - 1] + b[j]) + b[l(v[k] , j - 1)]]] += f[i][j - 1][k];
  81. if(p == 2 && q == 1) f[i][j][w[v[k] - 2 * b[j - 1] - b[j]]] += f[i][j - 1][k];
  82. if(p == 1 && q == 2 && i == x && j == y && v[k] == b[j - 1] + 2 * b[j]) ans += f[i][j - 1][k];
  83. }
  84. }
  85. }
  86. }
  87. printf("%lld\n" , ans);
  88. return 0;
  89. }

【bzoj3125】CITY 插头dp的更多相关文章

  1. HDU 4064 Carcassonne(插头DP)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4064 Problem Description Carcassonne is a tile-based ...

  2. ural1519插头DP

    1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB Background Regardless of the fact, that V ...

  3. 插头DP学习笔记——从入门到……????

    我们今天来学习插头DP??? BZOJ 2595:[Wc2008]游览计划 Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该 ...

  4. RUAL1519 Formula 1 【插头DP】

    RUAL1519 Formula 1 Background Regardless of the fact, that Vologda could not get rights to hold the ...

  5. URAL 1519 Formula 1(插头DP,入门题)

    Description Background Regardless of the fact, that Vologda could not get rights to hold the Winter ...

  6. URAL1519 Formula 1 —— 插头DP

    题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 secondMemory limit: 64 MB ...

  7. bzoj3125: CITY 题解

    3125: CITY Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 486  Solved: 213[Submit][Status][Discuss] ...

  8. [专题总结]初探插头dp

    彻彻底底写到自闭的一个专题. 就是大型分类讨论,压行+宏定义很有优势. 常用滚动数组+哈希表+位运算.当然还有轮廓线. Formula 1: 经过所有格子的哈密顿回路数. 每个非障碍点必须有且仅有2个 ...

  9. 「总结」插头$dp$

    集中做完了插头$dp$ 写一下题解. 一开始学的时候还是挺蒙的. 不过后来站在轮廓线$dp$的角度上来看就简单多了. 其实就是一种联通性$dp$,只不过情况比较多而已了. 本来转移方式有两种.逐行和逐 ...

随机推荐

  1. ubuntu下刻录优盘的命令

    fdisk -l  找到优盘为/dev/sdb4 sudo dd if=/home/alex/Desktop/kali-linux-2016.1-amd64.iso of=/dev/sdb4

  2. Nginx入门篇(四)之常用配置解析

    1.Nginx状态信息功能 Nginx的模块当中有一个ngx_http_stub_status_module模块,这个模块主要记录Nginx的基本访问信息,要使用该模块,需要在编译的时候增加http_ ...

  3. Repo 的使用小结

    一.安装 创建目录和修改环境变量 $ mkdir ~/bin $ PATH=~/bin:$PATH 下载repo代码 $ curl https://storage.googleapis.com/git ...

  4. cogs930找第k小的数(k-th number)

    cogs930找第k小的数(k-th number) 原题链接 题解 好题... 终极版是bzoj3065(然而并不会) 先讲这个题... 维护\(n+1\)个值域线段树(用主席树),标号\(0\) ...

  5. Maven学习(十)-----使用Maven创建Java项目

    所需要的工具: Maven 3.3.3 Eclipse 4.2 JDK 8 注意:请确保 Maven 是正确安装和配置(在Windows,*nix,Mac OSX系统中),然后再开始本教程,避免 mv ...

  6. 三、利用EnterpriseFrameWork快速开发Winform系统(C/S)

    EnterpriseFrameWork框架实例源代码下载: 实例下载 上一章讲解了开发Web系统的详细步骤,以书籍的管理作实例实现对书籍的增.删.改.查功能,本章接着上面的实例继续补充用Winform ...

  7. Jmeter使用HTTP代理服务器录制脚本

    使用Jmeter录制脚本通常使用Badboy工具录制或者Jmeter自带的HTTP代理服务器录制脚本,这里说一下使用HTTP代理服务器录制时遇到的问题. 1.  Jmeter安装 下载得到Jmeter ...

  8. 使用Photon引擎进行unity网络游戏开发(一)——Photon引擎简介

    使用Photon引擎进行unity网络游戏开发(一)--Photon引擎简介 Photon PUN Unity 网络游戏开发 Photon引擎简介: 1. 服务器引擎: 服 务 器 引 擎 介 绍 服 ...

  9. [转载]文件系统缓存dirty_ratio与dirty_background_ra

    原文地址:文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别作者:vincent 这两天在调优数据库性能的过程中需要降低操作系统文件Cache对数据库性能的影 ...

  10. PytorchZerotoAll学习笔记(四)--线性回归

    线性回归 # 导入 torch.torch.autograd的Variable模块import torch from torch.autograd import Variable # 生成需要回归需要 ...