hdu4285-circuits
题意
一个 \(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的更多相关文章
- 【hdu4285】 circuits
http://acm.hdu.edu.cn/showproblem.php?pid=4285 (题目链接) 题意 求不不能嵌套的回路个数为K的路径方案数. Solution 插头dp,时限卡得太紧了, ...
- 乱码电路(Garbled circuits)
乱码电路(Garbled circuits)是Andrew Yao教授在上世纪80年代发明的一种很聪明的技术.它可以让两个人针对某个算式来计算答案,而不需要知道他们在计算式所输入的数字. 举个例子说, ...
- HDU 3157 Crazy Circuits(有源汇上下界最小流)
HDU 3157 Crazy Circuits 题目链接 题意:一个电路板,上面有N个接线柱(标号1~N),还有两个电源接线柱 + -.给出一些线路,每一个线路有一个下限值求一个能够让全部部件正常工作 ...
- hdoj 3157 Crazy Circuits 【有下界最小流】
题目:hdoj 3157 Crazy Circuits 题意:如今要制造一个电路板.电路板上有 n 个电子元件,各个元件之间有单向的电流流向.然后有一个 + .电流进入, -- 电流汇入,然后推断能不 ...
- hdu Crazy Circuits
Crazy Circuits 题目: 给出一个电路板,从+极出发到负极. 如今给你电路板上的最小电流限制,要你在电流平衡的时候求得从正极出发的最小电流. 算法: 非常裸的有源汇最小流.安有源汇最大流做 ...
- specialized English for automation-Lesson 2 Basic Circuits of Operational Amplifiers
排版有点乱.... ========================================================================= Operational Ampl ...
- HDU 3157 Crazy Circuits (有源汇上下界最小流)
题意:一个电路板,上面有N个接线柱(标号1~N) 还有两个电源接线柱 + - 然后是 给出M个部件正负极的接线柱和最小电流,求一个可以让所有部件正常工作的总电流. 析:这是一个有源汇有上下界的 ...
- HDU 3157 Crazy Circuits
Crazy Circuits Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ...
- 香农的伟大论文《A Symbolic Analysis of Relay and Switching Circuits》
香农在1938年发表的伟大论文A Symbolic Analysis of Relay and Switching Circuits(<对继电器和开关电路中的符号分析>)将开关.继电器.二 ...
- HDU 4285 circuits( 插头dp , k回路 )
circuits Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- 微信小程序列表项滑动显示删除按钮
微信小程序并没有提供列表控件,所以也没有iOS上惯用的列表项左滑删除的功能,SO只能自己干了. 原理很简单,用2个层,上面的层显示正常的内容,下面的层显示一个删除按钮,就是记录手指滑动的距离,动态的来 ...
- 使用Serilog输出到ES(使用笔记)
第一步:安装Serilog 使用NuGet包安装以下组件: Serilog.AspNetCoreSerilog.Settings.ConfigurationSerilog.Sinks.ConsoleS ...
- maven scope属性值设置含义
1.枚举各个属性值的含义 compile,缺省值,适用于所有阶段,会打包进项目. provided,类似compile,期望JDK.容器或使用者会提供这个依赖. runtime,只在运行时使用,如JD ...
- Datawhale MySQL 训练营 Task4 表联结
学习内容 MySQL别名 列别名,将查询或者筛选出来列用AS 命名,如果有空格则需要引号 '' SELECT xxx AS xxxx FROM WHERE GROUP BY HAVING 表别名, 把 ...
- CentOS删除安装的程序
以mysql举例: 首先查询安装包: rpm -qa|grep mysql 查询到的一个结果为:mysql-community-libs-5.7.13-1.el6.x86_64 yum 删除 yum ...
- [文章存档]Kudu 的 Debug Console 窗口如何查看更多文件
链接:https://docs.azure.cn/zh-cn/articles/azure-operations-guide/app-service-web/aog-app-service-web-h ...
- React Native移动开发实战-5-Android平台的调试技巧
Android平台的调试和其他平台的调试也很类似,例如:在Android Studio打开的工程中,打开源码MainActivity.java,然后,将鼠标移至代码编辑区的左侧后,单击鼠标即可添加断点 ...
- [T-ARA][느낌 아니까][懂得那份感觉]
歌词来源:http://music.163.com/#/song?id=27808771 作曲 : 박덕상/박현중 [作曲 : p/bag-ddeog-ssang-/p/ba-Kyeon-c/jung ...
- OGG FOR BIGDATA 安装(修正)
参考:http://docs.oracle.com/goldengate/bd1221/gg-bd/GADBD/toc.htm 一.环境介绍 源:centos6.5 oracl e 11.20.4 ...
- Openresty(Lua+Nginx)实践
简介: OpenResty(也称为 ngx_openresty)是一个全功能的 Web 应用服务器.它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. OpenRest ...