题目大意:

找到多条回路覆盖所有非障碍格子,问这样回路的种数

这里的插头与URAL1519 不一样的是 只要管它是否存在即可,只需要1个二进制位表示状态

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream> using namespace std;
#define ll unsigned long long
const int HASH = ;
const int STATE = ;
const int MAXD = ;
int n , m ;
int code[MAXD] , mp[MAXD][MAXD]; struct HASHMAP{
int head[HASH] , next[STATE] , state[STATE] , size;
ll f[STATE]; void init(){
size = ;
memset(head , - , sizeof(head));
} void push_in(int st , ll sum){
int h = st%HASH;
for(int i = head[h] ; ~i ; i=next[i]){
if(st == state[i]){
f[i]+=sum;
return ;
}
}
f[size]=sum;
state[size] = st;
next[size] = head[h];
head[h] = size++;
}
}hashmap[]; void decode(int *code , int m , int st)
{
for(int i=m ; i>= ; i--){
code[i] = st&;
st>>=;
}
} int encode(int *code , int m)
{
int st=;
for(int i= ; i<=m ; i++){
st<<=;
st |= code[i];
}
return st;
} void init()
{
scanf("%d%d" , &n , &m);
for(int i= ; i<=n ; i++){
for(int j= ; j<=m ; j++){
scanf("%d" , &mp[i][j]);
}
}
} void shift(int *code , int m) //换行,可理解为将最右侧轮廓线换到了下一行的最左侧
{
for(int i=m ; i>= ; i--) code[i] = code[i-];
code[] = ;
} void dpblank(int i , int j , int cur) //处理可执行格子
{
// cout<<"ok: "<<i<<" "<<j<<endl;
int k , left , up;
for(k= ; k<hashmap[cur].size ; k++){
decode(code , m , hashmap[cur].state[k]);
left = code[j-];
up = code[j];
if(left&&up){ //插头均存在 1 1
code[j-] = code[j] = ;
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]);
// cout<<i<<" "<<j<<" "<<encode(code , m)<<" "<<hashmap[cur].f[k]<<endl;
}
else if(left || up){ // 1 || 1
if(j<m && mp[i][j+]){
//这里面右插头是可选的,所以不存在换行shift()
code[j-] = , code[j] = ;
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]);
}
if(i<n && mp[i+][j]){
code[j-] = , code[j] = ;
if(j == m) shift(code , m);
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]);
}
}
else {
if((j<m && mp[i][j+]) && (i<n && mp[i+][j])){
code[j-] = code[j] = ;
hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]);
}
}
}
} void dpblock(int i , int j , int cur)
{
// cout<<"flase: "<<i<<" "<<j<<endl;
int k , left , up;
for(k= ; k<hashmap[cur].size ; k++){
decode(code , m , hashmap[cur].state[k]);
left = code[j-] , up = code[j];
if(j == m) shift(code , m);
if(left+up == ) hashmap[cur^].push_in(encode(code , m) , hashmap[cur].f[k]);
}
} ll solve()
{
ll ans = ;
int cur = ;
hashmap[cur].init();
hashmap[cur].push_in( , );
for(int i= ; i<=n ; i++){
for(int j= ; j<=m ; j++){
hashmap[cur^].init();
if(mp[i][j]) dpblank(i , j , cur);
else dpblock(i , j , cur);
cur ^= ;
}
}
for(int i= ; i<hashmap[cur].size ; i++)
ans += hashmap[cur].f[i];
return ans;
} int main()
{
// freopen("in.txt" , "r" , stdin);
int T , cas=;
scanf("%d" , &T);
while(T--)
{
init();
printf("Case %d: There are %I64u ways to eat the trees.\n" , ++cas , solve());
}
return ;
}

HDU 1693 二进制表示的简单插头dp的更多相关文章

  1. HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)

    插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...

  2. HDU 1693 Eat the Trees(插头DP,入门题)

    Problem Description Most of us know that in the game called DotA(Defense of the Ancient), Pudge is a ...

  3. HDU 1693 Eat the Trees (插头DP)

    题意:给一个n*m的矩阵,为1时代表空格子,为0时代表障碍格子,问如果不经过障碍格子,可以画一至多个圆的话,有多少种方案?(n<12,m<12) 思路: 这题不需要用到最小表示法以及括号表 ...

  4. hdu 1693 : Eat the Trees 【插头dp 入门】

    题目链接 题意: 给出一个n*m大小的01矩阵,在其中画线连成封闭图形,其中对每一个值为1的方格,线要恰好穿入穿出共两次,对每一个值为0的方格,所画线不能经过. 参考资料: <基于连通性状态压缩 ...

  5. HDU 1565 方格取数(1) ——插头DP

    [题目分析] 其实直接状压就可以了. 但是有点闲,又写了一个可读性极差,智商低下,很(gou)好(pi)的代码 [代码] #include <cstdio> #include <cs ...

  6. hdu 4405 Aeroplane chess(简单概率dp 求期望)

    Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  7. TopCoder SRM 722 Div1 Problem 600 DominoTiling(简单插头DP)

    题意  给定一个$12*12$的矩阵,每个元素是'.'或'X'.现在要求$1*2$的骨牌铺满整个矩阵, 'X'处不能放置骨牌.求方案数. 这道题其实和 Uva11270 是差不多的,就是加了一些条件. ...

  8. hdu 1693 Eat the Trees——插头DP

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1693 第一道插头 DP ! 直接用二进制数表示状态即可. #include<cstdio> # ...

  9. HDU 1693 Eat the Trees(插头DP)

    题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...

随机推荐

  1. linux登录mysql

    mysql  -u 用户名 -p密码 mysql -u root -psqj888

  2. 让Fiddler能够检测到localhost的http数据

    用 vs.net开发调试网站程序时经常有这样的地址: http://localhost:2033/ 然而在开启 Fiddler 后会发现Fiddler 完全抓不到任何封包. 主要的原因是因为 Fidd ...

  3. Js_动画显示背景图片

    jAni是一个可以动画显示背景图片的jQuery插件.这个插件基本上是GIF动画的一个替代品,但是他有他的好处.所有浏览器都支持GIF形式的动画格式,而且也不需要额外的javaScript代码和标记. ...

  4. mysql 批处理文件--- 创建 用户 以及 导入数据

    在window下,通过批处理文件(.bat),进行开启MYSQL服务,导入数据文件(.sql) 1)新建一个txt文件,写入以下内容 rem 启动mysql56服务  mysql56是我的mysql服 ...

  5. CodeIgniter配置之SESSION

    刚使用Codeigniter时也被其中的SESSION迷惑过,后来就再也没用过CI自带的SESSION,想必还是有必要整理一下SESSION.为弄清CI中的SESSION,先来说一下PHP中SESSI ...

  6. import package的问题

    在新建class的时候除了名字还可以选择包名: 新建2个包名,然后在不同的包里写2个同名的类, 程序中导入另外一个包 package com.hs;import com.hy.Father; 当直接使 ...

  7. perl 语法速查

    同时学perl.python和shell脚本会很容易将它们的语法搞混,本文主要是一个个人的总结,方便要用时的查询. perl基本语法.安装.帮助文档 文件头格式: #!/usr/bin/perl us ...

  8. MHA的几种死法-叶良辰

    master不通      找到最新slave           找到有所有其他slave缺失relay log的 slave      选主           配置文件指定           ...

  9. Java_Ant 详解

    1,什么是antant是构建工具2,什么是构建概念到处可查到,形象来说,你要把代码从某个地方拿来,编译,再拷贝到某个地方去等等操作,当然不仅与此,但是主要用来干这个3,ant的好处跨平台   --因为 ...

  10. CentOS7+JDK8编译Hadoop2.6.4

    1. 下载相关软件 apache-maven-3.3.1-bin.tar.gz protobuf-2.5.0.tar.gz hadoop-2.6.4-src.tar.gz 2.配置好jdk8环境(请看 ...