题目大意:

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

这里的插头与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. Android 上千张图片的列表滑动加载

    一般项目中图片加载用的比较多的是ImageLoader 但是需求自己配置一些参数 上手有些复杂 对于手机图库中有上千张图片需要加载时 一个使用性能很好的库Glide可以解决 效果图如下 滑动非常流畅 ...

  2. iphone 使用技巧

    http://www.app111.com/doc/100147120_1.html(隐藏某个图标) (3)传视频  moliplayer 和itunes  ---应用(在下部)找到moliplaye ...

  3. POJ 2063 Investment 完全背包

    题目链接:http://poj.org/problem?id=2063 今天果然是卡题的一天.白天被hdu那道01背包的变形卡到现在还没想通就不说了,然后晚上又被这道有个不大也不小的坑的完全背包卡了好 ...

  4. POJ 3181 Dollar Dayz && Uva 147 Dollars(完全背包)

    首先是 Uva 147:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_p ...

  5. [js]事件综合 整理

    原文链接:http://www.cnblogs.com/xxcanghai/p/5205998.html 事件流:页面接收事件的顺序,IE提出了事件冒泡流,Netscape提出了事件捕获流. 事件冒泡 ...

  6. 扩展spring data jpa的数据更新方法时注意事项

    //此处必须加@Transactional,否则不能运行,报错 @Transactional @Modifying @Query("update ExamItem a set a.versi ...

  7. C#_抓包HttpWebRequest跟HttpWebResponse

    1.第一招,根据URL地址获取网页信息  这招是入门第一式, 特点: 1.最简单最直观的一种,入门课程. 2.适应于明文,无需登录,无需任何验证就可以进入的页面. 3.获取的数据类型为HTML文档. ...

  8. Java Performance - 优化和分析Garbage Collection/垃圾收集

    随着硬件的不断提升,Java Heap 越来越大,合理的垃圾收集调优变得愈发重要.下面介绍一些最佳实践: 注意: 下面不涉及 IBM AIX Java. 同时不介绍原理,仅仅是建议以及初始配置/最佳实 ...

  9. 基于dubbo源码包通过Maven构建dubbo的详细步骤

    通过Maven构建dubbo 既然可以下载得到源码以及发布包,那么为什么要去构建dubbo呢?,我们先来看下dubbo的主要模块: 我们不仅要使用dubbo的核心框架,还要使用它的一些服务,比如管理控 ...

  10. hiho_1290_demo_day

    题目大意 一个MxN的矩阵,矩阵中的有些方格中有障碍物,有些没有,有一个机器人从左上角出发,它只能有两种移动方式:一直向右移动,直到遇到障碍物:一直向下移动,直到遇到障碍物.     现在可以将矩阵中 ...