Description

Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic games of 20**, it is well-known, that the city will conduct one of the Formula 1 events. Surely, for such an important thing a new race circuit should be built as well as hotels, restaurants, international airport - everything for Formula 1 fans, who will flood the city soon. But when all the hotels and a half of the restaurants were built, it appeared, that at the site for the future circuit a lot of gophers lived in their holes. Since we like animals very much, ecologists will never allow to build the race circuit over the holes. So now the mayor is sitting sadly in his office and looking at the map of the circuit with all the holes plotted on it. Problem Who will be smart enough to draw a plan of the circuit and keep the city from inevitable disgrace? Of course, only true professionals - battle-hardened programmers from the first team of local technical university!.. But our heroes were not looking for easy life and set much more difficult problem: "Certainly, our mayor will be glad, if we find how many ways of building the circuit are there!" - they said. It should be said, that the circuit in Vologda is going to be rather simple. It will be a rectangle N*M cells in size with a single circuit segment built through each cell. Each segment should be parallel to one of rectangle's sides, so only right-angled bends may be on the circuit. At the picture below two samples are given for N = M = 4 (gray squares mean gopher holes, and the bold black line means the race circuit). There are no other ways to build the circuit here. 一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数

Input

The first line contains the integer numbers N and M (2 ≤ N, M ≤ 12). Each of the next N lines contains M characters, which are the corresponding cells of the rectangle. Character "." (full stop) means a cell, where a segment of the race circuit should be built, and character "*" (asterisk) - a cell, where a gopher hole is located.

Output

You should output the desired number of ways. It is guaranteed, that it does not exceed 2^63-1.

Sample Input

4 4
**..
....
....
....

Sample Output

2

解题思路:

发现一个格点一定有一进一出,就可以3进制表示括号序列轮廓线Dp就好了。

把该存的存入map/Hash表中,元素访问状态转移,要写好编码和解码。3进制改用4进制。

分类讨论一下,10种情况,画个图就好了。

方程只关心最后一个格点,可以滚动掉2维。

代码:(Hash挂链)

  1. #include<cstdio>
  2. #include<vector>
  3. #include<cstring>
  4. #include<algorithm>
  5. typedef long long lnt;
  6. typedef unsigned int uit;
  7. typedef long long unt;
  8. struct int_2{
  9. uit x;
  10. unt y;
  11. int_2(){}
  12. int_2(uit a,unt b){x=a;y=b;}
  13. };
  14. class Fast_map{
  15. #define mod 2333
  16. public:
  17. bool find(uit x)
  18. {
  19. int y=x%mod;
  20. for(int i=;i<to[y].size();i++)
  21. if(to[y][i].x==x)
  22. return true;
  23. return false;
  24. }
  25. void ins(uit x,unt v)
  26. {
  27. int f=x%mod;
  28. to[f].push_back(int_2(x,v));
  29. return ;
  30. }
  31. void add(uit x,unt v)
  32. {
  33. int f=x%mod;
  34. for(int i=;i<to[f].size();i++)
  35. if(to[f][i].x==x)
  36. {
  37. to[f][i].y+=v;
  38. return ;
  39. }
  40. return ;
  41. }
  42. void clear(void)
  43. {
  44. for(int i=;i<mod;i++)
  45. to[i].clear();
  46. return ;
  47. }
  48. void start(void)
  49. {
  50. jjj=;
  51. iii=;
  52. while(iii<mod&&!to[iii].size())
  53. iii++;
  54. return ;
  55. }
  56. bool going_on(void)
  57. {
  58.  
  59. return iii<mod;
  60. }
  61. void go(void)
  62. {
  63. jjj++;
  64. if(jjj<to[iii].size())
  65. return ;
  66. jjj=;
  67. iii++;
  68. while(iii<mod&&!to[iii].size())
  69. iii++;
  70. return ;
  71. }
  72. int_2 ite(void)
  73. {
  74. return to[iii][jjj];
  75. }
  76. void move(void)
  77. {
  78. for(int i=;i<mod;i++)
  79. for(int j=;j<to[i].size();j++)
  80. to[i][j].x<<=;
  81. return ;
  82. }
  83. private:
  84. std::vector<int_2>to[mod];
  85. int iii,jjj;
  86. #undef mod
  87. }dp[];
  88. int n,m;
  89. int p,q;
  90. int ei,ej;
  91. unt ans;
  92. char cmd[];
  93. bool mp[][];
  94. void update(int i,uit j,unt val)
  95. {
  96. if(!dp[i].find(j))
  97. dp[i].ins(j,val);
  98. else
  99. dp[i].add(j,val);
  100. return ;
  101. }
  102. uit change(uit x,int plc,uit val)
  103. {
  104. uit ans=x;
  105. uit cut=0ul-1ul;
  106. cut^=(<<(plc<<));
  107. cut^=(<<(plc<<|));
  108. ans&=cut;
  109. ans|=(val<<(plc<<));
  110. return ans;
  111. }
  112. int main()
  113. {
  114. memset(mp,,sizeof(mp));
  115. scanf("%d%d",&n,&m);
  116. for(int i=;i<=n;i++)
  117. {
  118. scanf("%s",cmd+);
  119. for(int j=;j<=m;j++)
  120. {
  121. if(cmd[j]=='.')
  122. {
  123. mp[i][j]=true;
  124. ei=i,ej=j;
  125. }
  126. }
  127. }
  128. p=,q=;
  129. dp[].ins(,);
  130. for(int i=;i<=n;i++)
  131. {
  132. for(int j=;j<=m;j++)
  133. {
  134. std::swap(p,q);
  135. dp[p].clear();
  136. for(dp[q].start();dp[q].going_on();dp[q].go())
  137. {
  138. int_2 state=dp[q].ite();
  139. uit s=state.x;
  140. unt v=state.y;
  141. uit tl=(s>>((j-)<<))&;
  142. uit tu=(s>>(j<<))&;
  143. if(!mp[i][j])
  144. {
  145. if(tl|tu);else
  146. update(p,s,v);
  147. }else{
  148. uit ts;
  149. if(tl==)
  150. {
  151. if(tu==)
  152. {
  153. if(mp[i][j+]&&mp[i+][j]);else continue;
  154. ts=change(s,j-,);
  155. ts=change(ts,j,);
  156. update(p,ts,v);
  157. }else if(tu==)
  158. {
  159. if(mp[i+][j])
  160. {
  161. ts=change(s,j-,);
  162. ts=change(ts,j,);
  163. update(p,ts,v);
  164. }
  165. if(mp[i][j+])
  166. {
  167. ts=change(s,j-,);
  168. ts=change(ts,j,);
  169. update(p,ts,v);
  170. }
  171. }else{
  172. if(mp[i+][j])
  173. {
  174. ts=change(s,j-,);
  175. ts=change(ts,j,);
  176. update(p,ts,v);
  177. }
  178. if(mp[i][j+])
  179. {
  180. ts=change(s,j-,);
  181. ts=change(ts,j,);
  182. update(p,ts,v);
  183. }
  184. }
  185. }else if(tl==)
  186. {
  187. if(tu==)
  188. {
  189. if(mp[i+][j])
  190. {
  191. ts=change(s,j-,);
  192. ts=change(ts,j,);
  193. update(p,ts,v);
  194. }
  195. if(mp[i][j+])
  196. {
  197. ts=change(s,j-,);
  198. ts=change(ts,j,);
  199. update(p,ts,v);
  200. }
  201. }else if(tu==)
  202. {
  203. int cnt=;
  204. for(int kt=j+;kt<=m;kt++)
  205. {
  206. if(((s>>(kt<<))&)==)
  207. cnt++;
  208. if(((s>>(kt<<))&)==)
  209. cnt--;
  210. if(!cnt)
  211. {
  212. ts=change(s,kt,);
  213. break;
  214. }
  215. }
  216. ts=change(ts,j-,);
  217. ts=change(ts,j,);
  218. update(p,ts,v);
  219. }else{
  220. if(i==ei&&j==ej)
  221. ans+=v;
  222. }
  223. }else{
  224. if(tu==)
  225. {
  226. if(mp[i+][j])
  227. {
  228. ts=change(s,j-,);
  229. ts=change(ts,j,);
  230. update(p,ts,v);
  231. }
  232. if(mp[i][j+])
  233. {
  234. ts=change(s,j-,);
  235. ts=change(ts,j,);
  236. update(p,ts,v);
  237. }
  238. }else if(tu==)
  239. {
  240. ts=change(s,j-,);
  241. ts=change(ts,j,);
  242. update(p,ts,v);
  243. }else{
  244. int cnt=-;
  245. for(int kt=j-;kt>=;kt--)
  246. {
  247. if(((s>>(kt<<))&)==)
  248. cnt++;
  249. if(((s>>(kt<<))&)==)
  250. cnt--;
  251. if(!cnt)
  252. {
  253. ts=change(s,kt,);
  254. break;
  255. }
  256. }
  257. ts=change(ts,j-,);
  258. ts=change(ts,j,);
  259. update(p,ts,v);
  260. }
  261. }
  262. }
  263. }
  264. }
  265. dp[p].move();
  266. }
  267. printf("%lld\n",ans);
  268. return ;
  269. }

代码(map)

  1. #include<map>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. typedef long long lnt;
  6. typedef unsigned int uit;
  7. typedef long long unt;
  8. using std::make_pair;
  9. int n,m;
  10. int p,q;
  11. int ei,ej;
  12. unt ans;
  13. char cmd[];
  14. bool mp[][];
  15. std::map<uit,unt>dp[],ooo;
  16. void update(int i,uit j,unt val)
  17. {
  18. if(dp[i].find(j)==dp[i].end())
  19. dp[i][j]=val;
  20. else
  21. dp[i][j]+=val;
  22. return ;
  23. }
  24. uit change(uit x,int plc,uit val)
  25. {
  26. uit ans=x;
  27. uit cut=0ul-1ul;
  28. cut^=(<<(plc<<));
  29. cut^=(<<(plc<<|));
  30. ans&=cut;
  31. ans|=(val<<(plc<<));
  32. return ans;
  33. }
  34. int main()
  35. {
  36. memset(mp,,sizeof(dp));
  37. scanf("%d%d",&n,&m);
  38. for(int i=;i<=n;i++)
  39. {
  40. scanf("%s",cmd+);
  41. for(int j=;j<=m;j++)
  42. {
  43. if(cmd[j]=='.')
  44. {
  45. mp[i][j]=true;
  46. ei=i,ej=j;
  47. }
  48. }
  49. }
  50. p=,q=;
  51. dp[][]=;
  52. for(int i=;i<=n;i++)
  53. {
  54. for(int j=;j<=m;j++)
  55. {
  56. std::swap(p,q);
  57. dp[p].clear();
  58. for(std::map<uit,unt>::iterator State=dp[q].begin();State!=dp[q].end();State++)
  59. {
  60. uit s=State->first;
  61. unt v=State->second;
  62. uit tl=(s>>((j-)<<))&;
  63. uit tu=(s>>(j<<))&;
  64. if(!mp[i][j])
  65. {
  66. if(tl|tu);else
  67. update(p,s,v);
  68. }else{
  69. uit ts;
  70. if(tl==)
  71. {
  72. if(tu==)
  73. {
  74. if(mp[i][j+]&&mp[i+][j]);else continue;
  75. ts=change(s,j-,);
  76. ts=change(ts,j,);
  77. update(p,ts,v);
  78. }else if(tu==)
  79. {
  80. if(mp[i+][j])
  81. {
  82. ts=change(s,j-,);
  83. ts=change(ts,j,);
  84. update(p,ts,v);
  85. }
  86. if(mp[i][j+])
  87. {
  88. ts=change(s,j-,);
  89. ts=change(ts,j,);
  90. update(p,ts,v);
  91. }
  92. }else{
  93. if(mp[i+][j])
  94. {
  95. ts=change(s,j-,);
  96. ts=change(ts,j,);
  97. update(p,ts,v);
  98. }
  99. if(mp[i][j+])
  100. {
  101. ts=change(s,j-,);
  102. ts=change(ts,j,);
  103. update(p,ts,v);
  104. }
  105. }
  106. }else if(tl==)
  107. {
  108. if(tu==)
  109. {
  110. if(mp[i+][j])
  111. {
  112. ts=change(s,j-,);
  113. ts=change(ts,j,);
  114. update(p,ts,v);
  115. }
  116. if(mp[i][j+])
  117. {
  118. ts=change(s,j-,);
  119. ts=change(ts,j,);
  120. update(p,ts,v);
  121. }
  122. }else if(tu==)
  123. {
  124. int cnt=;
  125. for(int kt=j+;kt<=m;kt++)
  126. {
  127. if(((s>>(kt<<))&)==)
  128. cnt++;
  129. if(((s>>(kt<<))&)==)
  130. cnt--;
  131. if(!cnt)
  132. {
  133. ts=change(s,kt,);
  134. break;
  135. }
  136. }
  137. ts=change(ts,j-,);
  138. ts=change(ts,j,);
  139. update(p,ts,v);
  140. }else{
  141. if(i==ei&&j==ej)
  142. ans+=v;
  143. }
  144. }else{
  145. if(tu==)
  146. {
  147. if(mp[i+][j])
  148. {
  149. ts=change(s,j-,);
  150. ts=change(ts,j,);
  151. update(p,ts,v);
  152. }
  153. if(mp[i][j+])
  154. {
  155. ts=change(s,j-,);
  156. ts=change(ts,j,);
  157. update(p,ts,v);
  158. }
  159. }else if(tu==)
  160. {
  161. ts=change(s,j-,);
  162. ts=change(ts,j,);
  163. update(p,ts,v);
  164. }else{
  165. int cnt=-;
  166. for(int kt=j-;kt>=;kt--)
  167. {
  168. if(((s>>(kt<<))&)==)
  169. cnt++;
  170. if(((s>>(kt<<))&)==)
  171. cnt--;
  172. if(!cnt)
  173. {
  174. ts=change(s,kt,);
  175. break;
  176. }
  177. }
  178. ts=change(ts,j-,);
  179. ts=change(ts,j,);
  180. update(p,ts,v);
  181. }
  182. }
  183. }
  184. }
  185. }
  186. ooo.clear();
  187. for(std::map<uit,unt>::iterator j=dp[p].begin();j!=dp[p].end();j++)
  188. if(!((j->first)>>(m<<)))
  189. ooo[((j->first)<<)]=j->second;
  190. dp[p].clear();
  191. for(std::map<uit,unt>::iterator j=ooo.begin();j!=ooo.end();j++)
  192. dp[p][j->first]=j->second;
  193. }
  194. printf("%lld\n",ans);
  195. return ;
  196. }

BZOJ1814: Ural 1519 Formula 1(插头Dp)的更多相关文章

  1. bzoj1814 Ural 1519 Formula 1(插头dp模板题)

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 924  Solved: 351[Submit][Sta ...

  2. 【BZOJ1814】Ural 1519 Formula 1 插头DP

    [BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...

  3. bzoj 1814 Ural 1519 Formula 1 插头DP

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 942  Solved: 356[Submit][Sta ...

  4. bzoj 1814 Ural 1519 Formula 1 ——插头DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1814 普通的插头 DP .但是调了很久.注意如果合并两个 1 的话,不是 “把向右第一个 2 ...

  5. Ural 1519 Formula 1 插头DP

    这是一道经典的插头DP单回路模板题. 用最小表示法来记录连通性,由于二进制的速度,考虑使用8进制. 1.当同时存在左.上插头的时候,需要判断两插头所在连通块是否相同,若相同,只能在最后一个非障碍点相连 ...

  6. bzoj 1814: Ural 1519 Formula 1 插头dp经典题

    用的括号序列,听说比较快. 然并不会预处理,只会每回暴力找匹配的括号. #include<iostream> #include<cstdio> #include<cstr ...

  7. bzoj1814 Ural 1519 Formula 1(插头DP)

    对插头DP的理解还不是很透彻. 先说一下肤浅的理解吧. 插头DP使用范围:指数级复杂度,且适用于解决网格图连通性问题,如哈密顿回路等问题.插头一般指每相邻2个网格的接口. 题目难度:一般不可做. 使用 ...

  8. 插头DP讲解+[BZOJ1814]:Ural 1519 Formula 1(插头DP)

    1.什么是插头$DP$? 插头$DP$是$CDQ$大佬在$2008$年的论文中提出的,是基于状压$D$P的一种更高级的$DP$多用于处理联通问题(路径问题,简单回路问题,多回路问题,广义回路问题,生成 ...

  9. 【Ural】1519. Formula 1 插头DP

    [题目]1519. Formula 1 [题意]给定n*m个方格图,有一些障碍格,求非障碍格的哈密顿回路数量.n,m<=12. [算法]插头DP [题解]<基于连通性状态压缩的动态规划问题 ...

随机推荐

  1. php session目录无法写进数据的问题

    打算开启php的session功能,并将session信息存到文件里. 修改php.ini,开启session功能: #将session信息存到文件中session.save_handler = fi ...

  2. C#中使用Dictionary实现Map数据结构——VC编程网

    转载自: http://blog.51cto.com/psnx168 在VC中使用过CMap以及在Java中使用过Map的朋友应该很熟悉,使用Map可以方便实现基于键值对数据的处理,在C#中,你就需要 ...

  3. bzoj1025 [SCOI2009]游戏 动态规划

    题目描述 对于一些长度为n的排列,将其作为一个置换,那么可能有一个自置换的次数使其回到1,2,3,...,n的情况.求对于所有能够回到1,2,3..,n的排列,不同的次数共有多少种. 题解来自黄学长 ...

  4. CF402E Strictly Positive Matrix(矩阵,强联通分量)

    题意 给定一个 n∗n 的矩阵 A,每个元素都非负判断是否存在一个整数 k 使得 A^k 的所有元素 >0 n≤2000(矩阵中[i][i]保证为1) 题解 考虑矩阵$A*A$的意义 ,设得到的 ...

  5. Systemd曝3漏洞,大部分Linux将受到攻击

    Linux 系统与服务管理工具 Systemd 被曝存在 3 大漏洞,影响几乎所有 Linux 发行版. Systemd 是 Linux 系统的基本构建块,它提供了对系统和服务的管理功能,以 PID ...

  6. 09-breack语句

  7. PatentTips - Virtualizing performance counters

    BACKGROUND Generally, the concept of virtualization in information processing systems allows multipl ...

  8. [Recompose] Pass a React Prop to a Stream in RxJS

    When you declare your Component and Props in JSX, you can pass those props along to your RxJS stream ...

  9. awk条件语句

    条件语句用于在运行操作之前做一个測试.在前面的章节中,我们看到了模式匹配规则的一些演示样例. 模式匹配规则本质上就是影响输入循环的条件表达式. 在这一部分,我们主要就在action中所使用的条件语句进 ...

  10. Find problem in eXtremeDB

    class table1 { char<8>    f1; char<80>  f2; uint4        f3; uint4        f4; double     ...