HDU 1693 二进制表示的简单插头dp
题目大意:
找到多条回路覆盖所有非障碍格子,问这样回路的种数
这里的插头与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的更多相关文章
- HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)
插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...
- 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 ...
- HDU 1693 Eat the Trees (插头DP)
题意:给一个n*m的矩阵,为1时代表空格子,为0时代表障碍格子,问如果不经过障碍格子,可以画一至多个圆的话,有多少种方案?(n<12,m<12) 思路: 这题不需要用到最小表示法以及括号表 ...
- hdu 1693 : Eat the Trees 【插头dp 入门】
题目链接 题意: 给出一个n*m大小的01矩阵,在其中画线连成封闭图形,其中对每一个值为1的方格,线要恰好穿入穿出共两次,对每一个值为0的方格,所画线不能经过. 参考资料: <基于连通性状态压缩 ...
- HDU 1565 方格取数(1) ——插头DP
[题目分析] 其实直接状压就可以了. 但是有点闲,又写了一个可读性极差,智商低下,很(gou)好(pi)的代码 [代码] #include <cstdio> #include <cs ...
- hdu 4405 Aeroplane chess(简单概率dp 求期望)
Aeroplane chess Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- TopCoder SRM 722 Div1 Problem 600 DominoTiling(简单插头DP)
题意 给定一个$12*12$的矩阵,每个元素是'.'或'X'.现在要求$1*2$的骨牌铺满整个矩阵, 'X'处不能放置骨牌.求方案数. 这道题其实和 Uva11270 是差不多的,就是加了一些条件. ...
- hdu 1693 Eat the Trees——插头DP
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1693 第一道插头 DP ! 直接用二进制数表示状态即可. #include<cstdio> # ...
- HDU 1693 Eat the Trees(插头DP)
题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...
随机推荐
- 转: 浅谈C/C++中的指针和数组(二)
转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...
- easyui 删除数据表格
1 最直接的方法: 返回的数据格式 Object rows:Array[3] 0:Object 1:Object 2:Object length:3 __proto__:A ...
- C#_微信支付V3
基础问题先排除: 确保 商户功能 审核通过,会有官方邮件 支付授权目录(注意看文档,大小写关系很大 点击支付按钮,提示“access_denied” 网上有很多关于此问题的解决) 点击支付按钮,提示“ ...
- 年轻人你活着不是为了看K线!
年轻人你活着不是为了看K线! 在网上看到一篇文章,写得还不错,转给大家看一下,内容如下: 这篇文章本来是该几年前写的,奉劝大家不要去玩股票.因为那个时候我的<中国崛起的经济学分析>这本 ...
- WordPress无法连接MySQL数据库
安装WordPress,需要配置MySQL数据库.配置好用户名和密码后居然还是报错. 通过抓包软件,发现根本没有数据包发往3306端口. 只能google之,发现是因为selinux的原因 解决方案: ...
- 20145218 《Java程序设计》第五周学习总结
20145218 <Java程序设计>第五周学习总结 教材学习内容总结 异常 程序中总有些意想不到的状况所引发的错误,如果不对异常进行正确的处理,则可能导致程序的中断执行,造成不必要的损失 ...
- spring来了-05-JDBC
概述 Spring对C3P0连接池的支持很完善 Spring对jdbc提供了JdbcTemplate,来简化jdbc操作, JdbcTemplate模板工具类,类似于DbUtils组件 JDBC: p ...
- $(document).ready(function (){}) , $(function(){}) , $().ready(function(){}) , jquery(function(){}) , (function($){})(jquery)有什么区别
$(document).ready(function(){...}) , $().ready(function(){...}) , $(function(){...}) , jquery(funct ...
- Android基础之项目结构分析
创建了第一个Android项目,用工具开发Android项目,我们有必要熟悉项目的目录结构,清楚各个项目下面放置的是什么东西.展开整个项目,其根目录结构(选用不同版本的SDK文件目录结构会有一些不同, ...
- [译]Quartz 框架 教程(中文版)2.2.x 之第一课 开始使用Quartz框架
第一课:开始使用Quartz框架 在你使用调度器之前,需要借助一些具体的例子去理解(谁愿意只是猜啊?).你可以使用SchedulerFactory类来达到程序调度的目的.有一些Quartz框架的用户可 ...