思路

同样是插头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. Python用摘要算法生成token及检验token

    原创作者:希希大队长,blog:https://cnblogs.com/dongxixi/ # 基础版,不依赖环境 import time import base64 import hashlib c ...

  2. NLP文本清理时常用的python小函数

    # coding = utf-8 import re 1. 清理杂七杂八字符 ''' [a-zA-Z0-9] 字母数字 [\u4e00-\u9fa5] 汉字的utf-8 code范围 ''' # 保留 ...

  3. [Cometoj#4 E]公共子序列_贪心_树状数组_动态规划

    公共子序列 题目链接:https://cometoj.com/contest/39/problem/E?problem_id=1585 数据范围:略. 题解: 首先可以考虑知道了$1$的个数和$3$的 ...

  4. linux_mysql学习系列

    Linux&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 网站架构系列文章:http://www.cnblogs.co ...

  5. 【转载】在一台电脑上运行两个或两个以上的tomcat

    作者注: 本片为转载文章,一台电脑运行两个及以上tomcat的原因是:第一个eclipse版本是4.5,最高支持tomcat8.0版本,并且这个版本的eclipse通过svn提交和更新项目极其缓慢,无 ...

  6. 深入理解C++11 C3

    继承构造函数 class A { public: A(int i):m_i(i) {} A(double d, int i):m_d(d),m_i(i){} private: int m_i{0}; ...

  7. LC 494. Target Sum

    问题描述 You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 ...

  8. 阿里巴巴矢量图标库(iconfont)批量全选的方法

    阿里巴巴矢量图标库: https://www.iconfont.cn/ 浏览器打开调试面板,进入 console 调试面板(Google浏览器快捷键F12)或者在页面空白处,点击右键->审查元素 ...

  9. python 基础例子 双色球 查询天气 查询电话

    # 随机生成双色球import random# 随机数 1-16之间# r = random.randint(1,16)# print(r)phone_numbers_str = "匪警[1 ...

  10. 让 history 命令显示日期和时间

    echo 'HISTTIMEFORMAT="%F %T "' >> /etc/profile source /etc/profile