思路

同样是插头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. Vue CLI 3 如何自定义 js 的文件名

    参考链接:https://blog.csdn.net/weixin_33979363/article/details/88742342

  2. 5个Linux性能命令

      使用几个命令就可以管理Linux系统的性能了,下面列出了5个最常用的Linux性能命令,包括top.vmstat.iostat.free和sar,它们有助于系统管理员快速解决性能问题. (1)to ...

  3. 服务器TIME_WAIT和CLOSE_WAIT区别及解决方案

    系统上线之后,通过如下语句查看服务器时,发现有不少TIME_WAIT和CLOSE_WAIT. netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) ...

  4. EXCEL 查找某个字符在字符串中最后一次出现的位置

    在EXCEL文档里想从很长的文件路径中取得文件名,[数据]→[分列]是个不错的选择,但用函数会显得更高大上一些. 首先,需要获取最后一个"\"所在的位置. 方法1: FIND(&q ...

  5. Photon Server 实现注册与登录(四) --- 服务端响应登陆和注册

    前面已经整理过了服务端代码,MyGameServer.cs 和 ClientPeer.cs 对请求和响应进行了拆分.接下来处理对前端的响应 一.响应登陆请求 之前整理中,响应前端请求主要在类Clien ...

  6. 15.Ansible安装与配置简单版

    Ansible是一个简单高效的自动化运维管理工具,用Python开发,能大批量管理N多台机器,可以并发的在多台机器上部署应用.安装软件.执行命令.配置和编排任务. 一.Ansible工作机制 从图中可 ...

  7. 【KMP】Censoring

    [KMP]Censoring 题目描述 Farmer John has purchased a subscription to Good Hooveskeeping magazine for his ...

  8. 怎样通过name属性获取元素节点集合

    使用 document.getElementsByName(); document.getElementsByName("userInfo") instanceof NodeLis ...

  9. springboot application.properties配置大全

    springboot application.properties配置大全 官方文档 https://docs.spring.io/spring-boot/docs/current/reference ...

  10. Linux下定时任务的查看及取消

    crontab -l 表示列出所有的定时任务 crontab -r 表示删除用户的定时任务,当执行此命令后,所有用户下面的定时任务会被删除,执行crontab -l后会提示用户:“no crontab ...