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的棋盘 ...
随机推荐
- Winform_播放声音文件
1.调用非托管的dll using System.Runtime.InteropServices; //DllImport命名空间的引用 class test //提示音 { [DllImport ...
- 利用SecureCRT上传、下载文件(使用sz与rz命令),超实用!
利用SecureCRT上传.下载文件(使用sz与rz命令),超实用! 文章来源:http://blog.csdn.net/dongqinliuzi/article/details/39623169 借 ...
- Sublime Text 3使用技巧
工欲善其事必先利其器,用了很多编辑器,pycharm.Eclipse.notepad++.ultra edit等等,要么是太卡,要么是太简陋 论性感,论轻便,论功能,我选Sublime Text 参考 ...
- 吐槽下近期的4G手机:
吐槽下近期的4G手机: 1.iphone6和6p,分别是4.7和5.5吋屏,1810和2915毫安时不可拆卸电池,双核64位苹果A8处理器.电池容量太小,不经用,中度使用一天一充,而且不支持VOOC闪 ...
- 判断手机连接的是fdd还是tdd的办法
判断手机连接的是fdd还是tdd的办法http://bbs.ydss.cn/thread-550035-1-1.html移动4G一般都是tdd,联通则可能有tdd,还有可能是fdd,判断手机连接的是t ...
- 【Problem solved】发现输入法都是仅桌面使用,无法输入中文时
你打开命令提示符输入CTFMON就可以啦.
- java复用和传参
java复用和传参的三种方法总结: (1) 直接在一个类中调用函数 : 1 package test1; 2 3 public class a 4 { 5 public static void get ...
- hibernate的懒加载问题
产生原因: 当使用hibernate查询一个对象的时候,如果Session关闭,再调用该对象关联的集合或者对象的时候,会产生懒加载异常! 解决方案: 方案一: 在Session关闭之前,查询对象关联的 ...
- 简化工作流程 10款必备的HTML5开发工具
利用HTML5工具不仅可以帮助设计师和开发者创建更具吸引力的网站,还能增加网站的可用性和可访问性.本文收集了10款HTML5开发工具让你在网页中搭建特效.动画.视频.音频等诸多功能,为你节省更多开发时 ...
- \bin\sh.exe:*** Couldn't reserve space for cygwin's heap,Win32 error 0
Git一直使用都好好的,今天git pull的时候,报了如下的错误,\bin\sh.exe:*** Couldn't reserve space for cygwin's heap,Win32 err ...