题意

一个 \(n\times m\) 的方格纸,有一些格子不能走。给出一个 \(k\) ,求有多少种方案,用 \(k\) 个不相交,不嵌套 的环覆盖所有可以走的格子。\(n,m\le 12\) 。

分析

若只有 \(k\) 个环的限制,那把它放进状态里就可以了。关键是如何解决不嵌套问题。我们在一个环形成的时候处理嵌套。若这个环被奇数个插头套着,那它至少会被它外层的那对插头形成的环包含,所以不转移。若是偶数个,那么接下来继续这样进行,就一定不会发生嵌套的情况。

为什么呢?考虑刚刚形成的这个环,外面的那层线,由于这个环被偶数个插头对套着,所以外层的线是被奇数个插头对套着,所以它一定不能成环,那么就会消除外面的两层。剩下的情况是一样的。

于是讨论一下,转移即可。

复杂度为 \(O(nm|s|)\) 。

这也算是插头dp棋盘模型的一个结束了。

代码

卡掉了所有的内置 hash_table 。终于手写了一次,因为不想改代码,所以实现了大部分接口,除了 map::iterator 不知道怎么实现,不过也不是很需要。

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ui;
typedef long long giant;
const int maxn=14;
const int maxs=3e5;
const ui haq=3e5+7;
const int q=1e9+7;
inline int Plus(int x,int y) {return ((giant)x+(giant)y)%q;}
inline void Pe(int &x,int y) {x=Plus(x,y);}
int n,m,ned;
bool no[maxn][maxn];
struct Hash {
struct E {
ui v;
int w,nxt;
} e[maxs];
int h[haq],tot;
inline void clear() {tot=0,memset(h,0,sizeof h);}
Hash () {clear();}
inline int& operator [] (ui x) {
ui wh=x%haq;
for (int i=h[wh];i;i=e[i].nxt) if (e[i].v==x) return e[i].w;
e[++tot]=(E){x,0,h[wh]};
return e[h[wh]=tot].w;
}
};
struct Map {
Hash *hs;
Map () {hs=new Hash();}
inline void clear() {hs->clear();}
inline int& operator [] (ui x) {return (*hs)[x];}
inline void swap(Map &o) {
std::swap(hs,o.hs);
}
} f,g;
void get(Map &g) {
for (int i=1;i<=g.hs->tot;++i) printf("[%llu]: %d, ",g.hs->e[i].v,g.hs->e[i].w);
puts("");
}
int mt[maxn];
inline ui get(ui x,int p) {
if (p==m+2) return x>>((m+2)<<1);
return (x>>(p<<1))&3;
}
inline ui mod(ui x,int p,ui d) {
if (p==m+2) {
ui bef=x&((1u<<((m+2)<<1))-1);
return bef+(d<<((m+2)<<1));
}
return (x&(~(3<<(p<<1))))+(d<<(p<<1));
}
inline void match(ui x,int *mt) {
static int sta[maxn];
int top=0;
for (int i=0;i<maxn;++i) mt[i]=0;
for (int i=1;i<=m+1;++i) {
const ui d=get(x,i);
if (d==1) sta[++top]=i; else if (d==2) {
int p=sta[top--];
mt[p]=i,mt[i]=p;
}
}
}
void dec(ui x) {
for (int j=1;j<=m+1;++j) printf("%llu ",get(x,j));
printf("%llu\n",get(x,m+2));
}
void work() {
scanf("%d%d%d",&n,&m,&ned);
memset(no,0,sizeof no);
for (int i=1;i<=n;++i) {
static char s[maxn];
scanf("%s",s+1);
for (int j=1;j<=m;++j) no[i][j]=(s[j]=='*');
}
if (ned>n*m/4) {
puts("0");
return;
}
f.clear(),g.clear();
f[0]=1;
for (int i=1;i<=n;++i) {
f.swap(g),f.clear();
for (int it=1;it<=g.hs->tot;++it) {
const ui &d=g.hs->e[it].v,s=get(d,m+2);
const int &w=g.hs->e[it].w;
if (get(d,m+1)==0) Pe(f[mod(mod(d,m+2,0)<<2,m+2,s)],w);
}
for (int j=1;j<=m;++j) {
f.swap(g),f.clear();
for (int it=1;it<=g.hs->tot;++it) {
const ui &d=g.hs->e[it].v,s=get(d,m+2),e=mod(mod(d,j,0),j+1,0),x=get(d,j),y=get(d,j+1);
const int &w=g.hs->e[it].w;
match(d,mt);
if (no[i][j]) {
if (x==0 && y==0) Pe(f[d],w);
continue;
}
if (x==0 && y==0) Pe(f[mod(mod(e,j,1),j+1,2)],w); else
if (x==0 || y==0) {
Pe(f[mod(e,j,x+y)],w);
Pe(f[mod(e,j+1,x+y)],w);
} else if (x==1 && y==1) Pe(f[mod(e,mt[j+1],1)],w);
else if (x==2 && y==2) Pe(f[mod(e,mt[j],2)],w);
else if (x==2 && y==1) Pe(f[e],w);
else if (x==1 && y==2) {
if (s>=ned) continue;
int cnt=0;
for (int k=1;k<j;++k) cnt+=(bool)get(d,k);
if (~cnt&1) Pe(f[mod(e,m+2,s+1)],w);
}
}
}
}
printf("%d\n",f[mod(0,m+2,ned)]);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
int T;
scanf("%d",&T);
while (T--) work();
return 0;
}

hdu4285-circuits的更多相关文章

  1. 【hdu4285】 circuits

    http://acm.hdu.edu.cn/showproblem.php?pid=4285 (题目链接) 题意 求不不能嵌套的回路个数为K的路径方案数. Solution 插头dp,时限卡得太紧了, ...

  2. 乱码电路(Garbled circuits)

    乱码电路(Garbled circuits)是Andrew Yao教授在上世纪80年代发明的一种很聪明的技术.它可以让两个人针对某个算式来计算答案,而不需要知道他们在计算式所输入的数字. 举个例子说, ...

  3. HDU 3157 Crazy Circuits(有源汇上下界最小流)

    HDU 3157 Crazy Circuits 题目链接 题意:一个电路板,上面有N个接线柱(标号1~N),还有两个电源接线柱 + -.给出一些线路,每一个线路有一个下限值求一个能够让全部部件正常工作 ...

  4. hdoj 3157 Crazy Circuits 【有下界最小流】

    题目:hdoj 3157 Crazy Circuits 题意:如今要制造一个电路板.电路板上有 n 个电子元件,各个元件之间有单向的电流流向.然后有一个 + .电流进入, -- 电流汇入,然后推断能不 ...

  5. hdu Crazy Circuits

    Crazy Circuits 题目: 给出一个电路板,从+极出发到负极. 如今给你电路板上的最小电流限制,要你在电流平衡的时候求得从正极出发的最小电流. 算法: 非常裸的有源汇最小流.安有源汇最大流做 ...

  6. specialized English for automation-Lesson 2 Basic Circuits of Operational Amplifiers

    排版有点乱.... ========================================================================= Operational Ampl ...

  7. HDU 3157 Crazy Circuits (有源汇上下界最小流)

    题意:一个电路板,上面有N个接线柱(标号1~N)   还有两个电源接线柱  +  - 然后是 给出M个部件正负极的接线柱和最小电流,求一个可以让所有部件正常工作的总电流. 析:这是一个有源汇有上下界的 ...

  8. HDU 3157 Crazy Circuits

    Crazy Circuits Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ...

  9. 香农的伟大论文《A Symbolic Analysis of Relay and Switching Circuits》

    香农在1938年发表的伟大论文A Symbolic Analysis of Relay and Switching Circuits(<对继电器和开关电路中的符号分析>)将开关.继电器.二 ...

  10. HDU 4285 circuits( 插头dp , k回路 )

    circuits Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. Tomcat 基础

    一.Tomcat服务器端口的配置 Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件是配置的核心文件. 如果想修改Tomcat服务器的启动端口,则可以在server.xml ...

  2. Python科学计算库-Numpy

    NumPy 是 Python 语言的一个扩充程序库.支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库,也是学习 python 必学的一个库. 1. 读取文件 numpy.gen ...

  3. 为什么你写的用例测不出Bug来?

    我们写测试用例的目的是为了能够整理思路,把要测试的地方列出来,做为知识的积淀,用例可以交给其他测试人员执行,或者是跟需求提出者进行讨论,对用例进行补充和修改.那么为啥你写的用例测不出Bug来呢,真的是 ...

  4. ThinkPHP学习笔记(一)----初识ThinkPHP

    在做微信开发的时候原本使用来yii框架,后续觉得yii虽然功能强大使用方便,但是整个框架太大了,不适合一些轻量级的开发:这个时候发现thinkphp这个框架,框架本身很小,只有几M,但麻雀虽小,但五脏 ...

  5. SQL Server Management Studio 键盘快捷键

    光标移动键盘快捷键 操作 SQL Server 2012 SQL Server 2008 R2 左移光标 向左键 向左键 右移光标 向右键 向右键 上移光标 向上键 向上键 下移光标 向下键 向下键 ...

  6. unset命令详解

    基础命令学习目录首页 功能说明:unset是一个内建的Unix shell命令,在Bourne shell家族(sh.ksh.bash等)和C shell家族(csh.tcsh等)都有实现.它可以取消 ...

  7. RabbitMQ基础使用之集群构建

    简介 RabbitMQ是基于Erlang开发的一种消息队列服务,本篇文章主要部署三台机器用来实现集群的普通模式与镜像模式!欢迎大家吐槽交流学习! 特点 集群节点包括内存节点和磁盘节点,有了磁盘节点就支 ...

  8. linux命令系列 grep

    grep, egrep, fgrep - print lines matching a pattern SYNOPSIS grep [OPTIONS] PATTERN [FILE...] grep [ ...

  9. js最简单的动画

    $(document).ready(function(){ //�ֶ�����ҳ��Ԫ�� $("#reset").click(function(){ $("*" ...

  10. ffmpeg——压缩mav格式音频

    今天偶然帮朋友压缩一个mav格式的音频.开始用压缩码率的方式,mav格式的音频体积一点都没变,查资料需要压缩音频文件的采样率和声道才能压缩mav格式的音频. 压缩要求是:将一个mav格式的音频文件,由 ...