Formula 1

题意

在\(n*m\)的矩阵中,有些格子有树,没有树的格子不能到达,找一条回路,吃完所有的树,求有多少种方法。

解法

因为只要一条回路,所以我们必须维护插头的连通性。

具体的可以参照 这位大佬的博客

代码

注意开long long。

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <cstring>
  5. #include <cctype>
  6. #define del(a,b) memset(a,b,sizeof(a))
  7. using namespace std;
  8. typedef long long ll;
  9. template <typename T>
  10. inline void read(T &x) {
  11. x=0;char c=getchar();T k=1;
  12. while(!isdigit(c)) {if(c=='-') k=-1;c=getchar();}
  13. while(isdigit(c)) {x=x*10+c-'0';c=getchar();}x*=k;
  14. }
  15. const int maxn=15;
  16. const int maxhash=100000;
  17. char G[maxn][maxn];
  18. int _hash[maxhash];
  19. ll sta[2][600000],sum[2][600000];
  20. int cur,n,m,en,em;
  21. int tot[2];
  22. int jz[maxn];
  23. void _init() {
  24. read(n),read(m);
  25. for(int i=1;i<=n;i++)
  26. for(int j=1;j<=m;j++) {
  27. cin>>G[i][j];
  28. if(G[i][j]=='.') en=i,em=j;
  29. }
  30. for(int i=1;i<=m;i++) jz[i]=i<<1;
  31. }
  32. void hash_insert(ll s,ll data) {
  33. int pos=s%maxhash;
  34. while(_hash[pos]) {
  35. if(sta[cur][_hash[pos]]==s) {
  36. sum[cur][_hash[pos]]+=data;
  37. return;
  38. }
  39. if(++pos==maxhash) pos=0;
  40. }
  41. ++tot[cur];
  42. _hash[pos]=tot[cur];
  43. sta[cur][tot[cur]]=s;sum[cur][tot[cur]]=data;
  44. }
  45. ll ans;
  46. void work() {
  47. tot[0]=1;sum[0][1]=1;
  48. for(int i=1;i<=n;i++) {
  49. for(int k=1;k<=tot[cur];k++)
  50. sta[cur][k]=sta[cur][k]<<2;
  51. for(int j=1;j<=m;j++) {
  52. cur^=1;
  53. tot[cur]=0;
  54. del(_hash,0);
  55. del(sta[cur],0);
  56. del(sum[cur],0);
  57. for(int k=1;k<=tot[1-cur];k++) {
  58. ll s=sta[1-cur][k],data=sum[1-cur][k];
  59. int x=(s>>jz[j-1])%4;
  60. int y=(s>>jz[j])%4;
  61. ll temp;
  62. if(G[i][j]!='.') {
  63. if(x==0&&y==0) hash_insert(s,data);
  64. }
  65. else {
  66. if(x==0&&y==0) {
  67. if(G[i][j+1]=='.'&&G[i+1][j]=='.') {
  68. temp=s+1*(1<<jz[j-1])+2*(1<<jz[j]);
  69. hash_insert(temp,data);
  70. }
  71. continue;
  72. }
  73. if(x==0&&y>0) {
  74. if(G[i][j+1]=='.')
  75. hash_insert(s,data);
  76. if(G[i+1][j]=='.') {
  77. temp=s-y*(1<<jz[j])+y*(1<<jz[j-1]);
  78. hash_insert(temp,data);
  79. }
  80. continue;
  81. }
  82. if(x>0&&y==0) {
  83. if(G[i+1][j]=='.')
  84. hash_insert(s,data);
  85. if(G[i][j+1]=='.') {
  86. temp=s-x*(1<<jz[j-1])+x*(1<<jz[j]);
  87. hash_insert(temp,data);
  88. }
  89. continue;
  90. }
  91. if(x==1&&y==1) {
  92. int f=1;
  93. for(int v=j+1;v<=m;v++) {
  94. int fff=(s>>jz[v])%4;
  95. if(fff==1) f++;
  96. if(fff==2) f--;
  97. if(!f) {
  98. temp=s-2*(1<<jz[v])+1*(1<<jz[v]);
  99. break;
  100. }
  101. }
  102. temp=temp-1*(1<<jz[j-1])-1*(1<<jz[j]);
  103. hash_insert(temp,data);
  104. continue;
  105. }
  106. if(x==2&&y==2) {
  107. int f=1;
  108. for(int v=j-2;v>=1;v--) {
  109. int fff=(s>>jz[v])%4;
  110. if(fff==1) f--;
  111. if(fff==2) f++;
  112. if(!f) {
  113. temp=s-1*(1<<jz[v])+2*(1<<jz[v]);
  114. break;
  115. }
  116. }
  117. temp=temp-2*(1<<jz[j-1])-2*(1<<jz[j]);
  118. hash_insert(temp,data);
  119. continue;
  120. }
  121. if(x==2&&y==1) {
  122. temp=s-2*(1<<jz[j-1])-1*(1<<jz[j]);
  123. hash_insert(temp,data);
  124. continue;
  125. }
  126. if(x==1&&y==2) {
  127. if(i==en&&j==em) {
  128. ans+=data;
  129. }
  130. }
  131. }
  132. }
  133. }
  134. }
  135. }
  136. int main() {
  137. _init();
  138. work();
  139. printf("%lld\n",ans);
  140. return 0;
  141. }

bzoj 1814 Fornula 1的更多相关文章

  1. 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 ...

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

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

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

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

  4. bzoj 1814: Ural 1519 Formula 1【插头dp】

    设f[i][j][s]为轮廓线推到格子(i,j),状态为s的方案数 括号表示一段线的左端和右端,表示成左括号和右括号,状压的时候用1和2表示,0表示已经闭合 下面的蓝线是黄色格子的轮廓线,dp转移要把 ...

  5. 插头DP题目泛做(为了对应WYD的课件)

    题目1:BZOJ 1814 URAL 1519 Formula 1 题目大意:给定一个N*M的棋盘,上面有障碍格子.求一个经过所有非障碍格子形成的回路的数量. 插头DP入门题.记录连通分量. #inc ...

  6. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  7. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  8. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  9. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

随机推荐

  1. Bash 如何取得当前正在执行的脚本的绝对路径?

    转自:http://blogread.cn/it/article/6549?f=wb Bash 如何取得当前正在执行的脚本的绝对路径? 如题,一般我们写Shell脚本的时候,都倾向使用绝对路径,这样无 ...

  2. redis实现集群加主从复制

    a)原理 (1)前提背景:如何解决redis横向扩展的问题----redis集群实现方式 (2)介绍redis 集群 ① Redis 集群是一个提供在多个Redis间节点间共享数据的程序集 ② 优势: ...

  3. 刷新linux硬盘存储接口

    #!/bin/bash for i in /sys/class/scsi_host/*; do echo "- - -" > $i/scan; done 简写 for i i ...

  4. preload、prefetch的认识

    预加载 现在的网络情况虽然很乐观,但是 defer和async 当浏览器碰到 script 脚本的时候: <script src="script.js"></sc ...

  5. Django入门--模板变量、过滤器及静态文件

    一.模板变量 我们登录页面后,在页面上会显示姓名等信息,姓名就是模板变量,用来显示登陆者的名字,Django对这些数据进行处理后,返回给前端页面,前端页面进行渲染. 1.模板变量语法规则 1)在htm ...

  6. 绘图-CAD-改快捷键

    CAD的快捷键应该在左手边,左手不离开键盘,右手不离开鼠标,这样的操作才有效率. arc 圆弧命令原命令是ARC Q 圆(CIRCLE) C 原快捷键C被定义为COPY,Q的形状类似圆,只是多了一个尾 ...

  7. Mysql 下DELETE操作表别名问题

    在用DELETE删除mysql数据库数据时采取一下两种方式: 方式一:DELETE FROM B_PROSON WHERE ID = 1; 不使用别名 方式二:DELETE BP FROM B_PRO ...

  8. [Office]PPT 2013如何设置图片为半透明?

    PPT里面似乎无法直接为图片设置透明度属性.下面是一种变通的办法. 1,插入一个和图片大小一致的图形(矩形):2,右键插入的矩形,然后在属性设置里选择“图片填充”,选择以需要的图片填充到该矩形里:3, ...

  9. plsql解决64位解决办法

    plsql解决64位解决办法 设置PLSQL Developer访问本机64位Oracle 由于在本机Windows Server 2008 R2 X64上安装了64位的Oracle 11.2.0.1 ...

  10. CSDN--十年

    昨天获得了博客专家的勋章,惊喜总是来的有点意外.这个勋章也算是来的一波三折.借着这个机会,回首一下我在CSDN的博客历史. 这个博客如今可查的最早的文章,是04年下半年写的,事实上之前应该另一些自己写 ...