思路

同样是插头DP,但是这题因为可以形成多个回路,所以左右括号是没有区别的,只需要01就可以表示了

注意if的嵌套关系

注意全零矩阵也要输出1

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int HASHsize = 400000;
int mat[20][20],n,m,T,pos[40];
int cnt[2],now,last,ans,endx,endy,fir[HASHsize+10],nxt[HASHsize+10],val[2][HASHsize+10],times[2][HASHsize+10];
void init(void){
memset(mat,0,sizeof(mat));
memset(cnt,0,sizeof(cnt));
now=0,last=0,ans=0,endx=0,endy=0;
memset(fir,0,sizeof(fir));
memset(nxt,0,sizeof(nxt));
memset(val,0,sizeof(val));
memset(times,0,sizeof(times));
}
void insert(int c,int num){
int t=c%HASHsize;
for(int i=fir[t];i;i=nxt[i]){
if(val[now][i]==c){
times[now][i]+=num;
return;
}
}
++cnt[now];
val[now][cnt[now]]=c;
times[now][cnt[now]]=num;
nxt[cnt[now]]=fir[t];
fir[t]=cnt[now];
}
void print(int x){
for(int i=0;i<m+1;i++)
printf("%lld",(x>>i)&1);
printf("\n");
}
void dp(void){
now=0;
insert(0,1);
for(int i=1;i<=n;i++){
for(int k=1;k<=cnt[now];k++)
val[now][k]<<=1;
for(int j=1;j<=m;j++){
last=now;
now^=1;
cnt[now]=0;
memset(fir,0,sizeof(fir));
memset(nxt,0,sizeof(nxt));
// printf("i=%lld j=%lld\n",i,j);
for(int k=1;k<=cnt[last];k++){
int state=val[last][k],num=times[last][k],plugL=(state>>(j-1))&1,plugU=(state>>(j))&1;
// printf("num=%lld\n",num);
// print(state);
// printf("plugL=%lld plugU=%lld\n",plugL,plugU);
if(mat[i][j]){
//新建连通分量
if((!plugL)&&(!plugU)){
if(mat[i+1][j]&&mat[i][j+1])
insert(state+(1<<(j-1))+(1<<(j)),num);
}
//合并联通分量
else if(plugL&&plugU){
if(i==endx&&j==endy)
ans+=num;
else
insert(state-(1<<(j-1))-(1<<(j)),num);
}
//延续联通分量
else{
if(plugL){
// printf("!\n");
if(mat[i+1][j])
insert(state,num);
if(mat[i][j+1])
insert(state-(1<<(j-1))+(1<<(j)),num);
}
if(plugU){
if(mat[i+1][j])
insert(state-(1<<(j))+(1<<(j-1)),num);
if(mat[i][j+1])
insert(state,num);
}
}
}
else{
if((!plugL)&&(!plugU))
insert(state,num);
}
}
}
}
}
signed main(){
scanf("%lld",&T);
pos[0]=1;
for(int i=1;i<30;i++)
pos[i]=pos[i-1]<<1;
while(T--){
bool isok=true;
init();
scanf("%lld %lld",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
scanf("%lld",&mat[i][j]);
if(mat[i][j]){
endx=i;endy=j;
isok=false;
}
}
// printf("endx=%lld endy=%lld\n",endx,endy);
if(!isok){
dp();
printf("%lld\n",ans);
}
else{
printf("1\n");
}
}
return 0;
}

P5074 Eat the Trees的更多相关文章

  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

    http://acm.hdu.edu.cn/showproblem.php?pid=1693 题意:n×m的棋盘求简单回路(可以多条)覆盖整个棋盘的方案,障碍格不许摆放.(n,m<=11) #i ...

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

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

  4. HDU 1693 Eat the Trees

    第一道(可能也是最后一道)插头dp.... 总算是领略了它的魅力... #include<iostream> #include<cstdio> #include<cstr ...

  5. 【HDOJ】【1693】Eat The Trees

    插头DP 插头dp模板题…… 这题比CDQ论文上的例题还要简单……因为不用区分左右插头(这题可以多回路,并不是一条哈密尔顿路) 硬枚举当前位置的状态就好了>_< 题解:http://blo ...

  6. Eat the Trees hdu 1693

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

  7. HDU - 1693 Eat the Trees(多回路插头DP)

    题目大意:要求你将全部非障碍格子都走一遍,形成回路(能够多回路),问有多少种方法 解题思路: 參考基于连通性状态压缩的动态规划问题 - 陈丹琦 下面为代码 #include<cstdio> ...

  8. HDU1693 Eat the Trees 插头dp

    原文链接http://www.cnblogs.com/zhouzhendong/p/8433484.html 题目传送门 - HDU1693 题意概括 多回路经过所有格子的方案数. 做法 最基础的插头 ...

  9. 【HDU1693】Eat the Trees(插头dp)

    [HDU1693]Eat the Trees(插头dp) 题面 HDU Vjudge 大概就是网格图上有些点不能走,现在要找到若干条不相交的哈密顿回路使得所有格子都恰好被走过一遍. 题解 这题的弱化版 ...

随机推荐

  1. 基于mxgraph.js开发的流程图组件

    1.fabric.js 在决定使用mxgraph.js开发流程图之前,尝试过用fabric.js来开发,结果发现并没有想象中的那么简单,而且用户体验非常差,下面是体验地址:workFlow直到遇到一个 ...

  2. sqlmap(网站数据库注入)

    *教程 http://www.nxadmin.com/tools/1241.html 一.ASP网站 1. sqlmap -u “http://www.czypjx.com/News_show.asp ...

  3. Docker通过挂载安装mysql

    一.安装 mkdir -p ./docker/mysql cd docker/ cd mysql/ mkdir conf mkdir data mkdir logs  mkdir mysql-file ...

  4. Servlet的request和response

    SERVLET API中forward() 与redirect()的区别?  答:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址:后者则是完全的跳转,浏览器将会得到跳转的地址 ...

  5. 常见的几种web攻击

    1. SQL注入 2. OS命令注入 3. 跨站脚本攻击(XSS) 4. HTTP首部注入 5. 会话劫持 6. 跨站点请求伪造(CSRF) 7. 点击劫持 8. DoS

  6. Linux系列(12)之例行工作调度

    你知道工作调度有哪几种吗? 你知道在进行工作调度时需要哪些服务在运行吗? 你知道突发性工作调度的指令at的用法吗? 知道如何管理at的工作调度吗? 知道at指令进行工作调度的原理吗? 知道什么是背景任 ...

  7. 【调试经验】C++和C的混合编程以及库调用

    问题背景 这两天在移植一个开源的库,偏底层的那种,所以对架构有一些依赖.源码的编译是通过Makefile来构建,怎奈公司的架构用的是CMAKE,所以就在开源的顶层和子目录分别构建了CMakeList, ...

  8. 编写程序模拟strlwr()和strupr()函数功能

    strlwr(字符串)strlwr()的作用是将字符串中大写字母转换成小写字母 strupr(字符串)strupr()的作用是将字符串中小写字母转换成大写字母 /* strlwr(字符串) strlw ...

  9. 贝叶斯优化 Bayesian Optimization

    贝叶斯优化 Bayesian Optimization 2018年07月02日 22:28:06 余生最年轻 阅读数 4821更多 分类专栏: 机器学习   版权声明:本文为博主原创文章,遵循CC 4 ...

  10. 怎样获取当前文档所有的元素节点(即html标签节点)

    方法1. 使用 document.getElementsByTagName("*"); 方法2. 使用document.querySelectorAll("*" ...