传送门

轮廓线dpdpdp模板题。

题意简述:给一个放有障碍的网格图,问有多少种方法能使所有非障碍格子都在同一条哈密顿回路上面。


考虑用括号序列的写法来状压这个轮廓线。

用000表示没有插头,111表示有插头,且是左括号,222表示有插头,且是右括号。

然后分类讨论一波:

  1. 对于当前的格子左边,上边都有插头。
  2. 只有左边有插头。
  3. 只有上边有插头。
  4. 左边,上边都没有插头。

其中第一种还要分类讨论一波:

  1. 两个插头都是左括号。
  2. 两个插头都是右括号
  3. 左边的是左括号,右边的是右括号
  4. 左边的是右括号,右边的是左括号

然后注意细节转移即可,注意如果像我一样用四进制实现三进制的话要手写一波hashhashhash表。

代码:

  1. #include<bits/stdc++.h>
  2. #include<tr1/unordered_map>
  3. #define ri register int
  4. using namespace std;
  5. using namespace tr1;
  6. typedef long long ll;
  7. int n,m,zx=-1,zy=-1,cur;
  8. bool mp[15][15];
  9. char s[15];
  10. ll ans=0;
  11. const int mod=1e6+7;
  12. struct Statement{
  13. int tot,idx[mod],sta[mod];
  14. ll num[mod];
  15. inline void clear(){memset(idx,-1,sizeof(idx)),tot=0;}
  16. inline void insert(int stat,ll nume){
  17. int pos=stat%mod;
  18. if(!pos)++pos;
  19. while(~idx[pos]&&sta[idx[pos]]!=stat)pos=pos==mod-1?1:pos+1;
  20. if(~idx[pos])num[idx[pos]]+=nume;
  21. else sta[idx[pos]=++tot]=stat,num[tot]=nume;
  22. }
  23. }f[2];
  24. inline int getbit(int x,int p){return (x>>((p-1)<<1))&3;}
  25. inline void update(int&x,int p,int v){x^=((v&3)^getbit(x,p))<<((p-1)<<1);}
  26. inline void solve(){
  27. cur=0,f[cur].clear(),f[cur].insert(0,1);
  28. for(ri i=1;i<=n;++i){
  29. for(ri j=1;j<=m;++j){
  30. cur^=1,f[cur].clear();
  31. for(ri tt=1;tt<=f[cur^1].tot;++tt){
  32. int stat=f[cur^1].sta[tt],p=getbit(stat,j),q=getbit(stat,j+1);
  33. ll dpnum=f[cur^1].num[tt];
  34. if(!mp[i][j]){if(!(p+q))f[cur].insert(stat,dpnum);continue;}
  35. if(!(p+q)){
  36. if(mp[i][j+1]&&mp[i+1][j])update(stat,j,1),update(stat,j+1,2),f[cur].insert(stat,dpnum);
  37. continue;
  38. }
  39. if(!p){
  40. if(mp[i][j+1])f[cur].insert(stat,dpnum);
  41. if(mp[i+1][j])update(stat,j,q),update(stat,j+1,0),f[cur].insert(stat,dpnum);
  42. continue;
  43. }
  44. if(!q){
  45. if(mp[i+1][j])f[cur].insert(stat,dpnum);
  46. if(mp[i][j+1])update(stat,j,0),update(stat,j+1,p),f[cur].insert(stat,dpnum);
  47. continue;
  48. }
  49. if(p==1&&q==2){if(i==zx&&j==zy)ans+=dpnum;continue;}
  50. update(stat,j,0),update(stat,j+1,0);
  51. if(p==2&&q==1){f[cur].insert(stat,dpnum);continue;}
  52. if(p==1){
  53. int cnt=1;
  54. for(ri k=j+2;k<=m+1;++k){
  55. int bit=getbit(stat,k);
  56. if(bit==1)++cnt;
  57. if(bit==2)--cnt;
  58. if(!cnt){update(stat,k,1);break;}
  59. }
  60. f[cur].insert(stat,dpnum);
  61. continue;
  62. }
  63. int cnt=-1;
  64. for(ri k=j-1;k;--k){
  65. int bit=getbit(stat,k);
  66. if(bit==1)++cnt;
  67. if(bit==2)--cnt;
  68. if(!cnt){update(stat,k,2);break;}
  69. }
  70. f[cur].insert(stat,dpnum);
  71. }
  72. }
  73. for(ri j=1;j<=f[cur].tot;++j)f[cur].sta[j]<<=2;
  74. }
  75. }
  76. int main(){
  77. scanf("%d%d",&n,&m);
  78. for(ri i=1;i<=n;++i){
  79. scanf("%s",s+1);
  80. for(ri j=1;j<=m;++j){
  81. mp[i][j]=s[j]=='.';
  82. if(mp[i][j])zx=i,zy=j;
  83. }
  84. }
  85. if(zx==-1)return puts("-1"),0;
  86. solve();
  87. cout<<ans;
  88. return 0;
  89. }

2019.01.23 ural1519 Formula 1(轮廓线dp)的更多相关文章

  1. 2019.01.23 hdu3377 Plan(轮廓线dp)

    传送门 题意简述:给一个n*m的带权矩阵,求从左上角走到右下角的最大分数,每个格子只能经过最多一次,n,m≤9n,m\le9n,m≤9. 思路: 考虑轮廓线dpdpdp,但这道题并没有出现回路的限制因 ...

  2. 2019.01.23 hdu1964 Pipes(轮廓线dp)

    传送门 题意简述:给一个没有障碍的网格图,任意两个格子连通需要花费一定代价,现在求一条覆盖所有格子的哈密顿回路的总权值的最小值. 思路: 跟这道题一毛一样,除了把求和变成求最小值以外. 代码: #in ...

  3. 2019.01.24 bzoj3125: CITY(轮廓线dp)

    传送门 题意简述:给一个n∗mn*mn∗m的网格图,有的格子不能走,有的格子只能竖着走,有的格子只能横着走,问用一条回路覆盖所有能走的格子的方案数. 思路: 就是简单的轮廓线dpdpdp加了一点限制而 ...

  4. 2019.01.24 bzoj2310: ParkII(轮廓线dp)

    传送门 题意简述:给一个m*n的矩阵,每个格子有权值V(i,j) (可能为负数),要求找一条路径,使得每个点最多经过一次且点权值之和最大. 思路:我们将求回路时的状态定义改进一下. 现在由于求的是路径 ...

  5. 2019.01.23 hdu1693 Eat the Trees(轮廓线dp)

    传送门 题意简述:给一个有障碍的网格图,问用若干个不相交的回路覆盖所有非障碍格子的方案数. 思路:轮廓线dpdpdp的模板题. 同样是讨论插头的情况,只不过没有前一道题复杂,不懂的看代码吧. 代码: ...

  6. URAL1519 Formula 1 —— 插头DP

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

  7. [URAL1519] Formula 1 [插头dp入门]

    题面: 传送门 思路: 插头dp基础教程 先理解一下题意:实际上就是要你求这个棋盘中的哈密顿回路个数,障碍不能走 看到这个数据范围,还有回路处理,就想到使用插头dp来做了 观察一下发现,这道题因为都是 ...

  8. 梦想Android版CAD控件2019.01.23更新

    下载地址:http://www.mxdraw.com/ndetail_10121.html?tdsourcetag=s_pcqq_aiomsg1. 增加异步读取CAD,DWG文件函数,MxFuncti ...

  9. 【NOI2019模拟2019.7.1】三格骨牌(轮廓线dp转杨图上钩子定理)

    Description \(n,m<=1e4,mod ~1e9+7\) 题解: 显然右边那个图形只有旋转90°和270°后才能放置. 先考虑一个暴力的轮廓线dp: 假设已经放了编号前i的骨牌,那 ...

随机推荐

  1. Vue之组件

    Vue之全局组件 全局组件可以被任何局部组件调用 <div id="app"> <!--这里是组件的使用--> <global-component&g ...

  2. 善于利用python中的os模块

    作为一个程序猿,平时善于利用python中的os模块进行路径等操作,会省去很多麻烦,下面总结一下我平时经常用到的方法: import os os.getcwd() # 获取当前文件所在的目录 os.p ...

  3. 199. Binary Tree Right Side View (Tree, Stack)

    Given a binary tree, imagine yourself standing on the right side of it, return the values of the nod ...

  4. json 相关知识

    一:json标准格式: 标准JSON的合法符号:{(左大括号)  }(右大括号)  "(双引号)  :(冒号)  ,(逗号)  [(左中括号)  ](右中括号) JSON字符串:特殊字符可在 ...

  5. Fibonacci again and again

    Fibonacci again and again http://acm.hdu.edu.cn/showproblem.php?pid=1848 Time Limit: 1000/1000 MS (J ...

  6. java命令启动jacocoagent及生成报告

    启动jacocoagent: java -Xms1024m -Xmx2048m -XX:-UseGCOverheadLimit -Ddruid.keepAlive=true -javaagent:/h ...

  7. spirng中的asm与jdk不兼容<已解决>

    转载自:spirng中的asm与jdk不兼容<已解决> 前言 不知道前面对eclipse做了什么,使用maven来创建项目,然后转成web,启动的时候一直报错.我弄了好久,还是无法解决,先 ...

  8. mysql 添加权限和撤销权限的实例(亲测可行)

    将当前数据库的表role_modules 的select权限赋予给用户uwangq: GRANT SELECT ON role_modules TO uwangq@'%' IDENTIFIED BY ...

  9. js的回调函数详解

    本文主要介绍了个人对于javascript中回调函数的理解和使用方法及示例,需要的朋友可以参考下   现在做native App  和Web App是主流,也就是说现在各种基于浏览器的web app框 ...

  10. js generator

    generator(生成器)是ES6标准引入的新的数据类型.一个generator看上去像一个函数,但可以返回多次. generator跟函数很像,定义如下: function* foo(x) { y ...