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 ...
随机推荐
- 常见面试算法题JS实现-仅用递归函数和栈操作逆序一个栈
前言: 因为JAVA和JS语言特性的不同,有些东西在JAVA中可能需要一些技巧和手段才能实现的复杂程序,但是在JS中可能就是天然存在的,所以这套书里面的题目不会全部用JS去实现一遍,因为可能JS的实现 ...
- 并发系列(二)----Java内存模型
一 简介 在并发编程中,两个线程(A.B)同时操作一个普通变量的时候会出现线程A在操作变量时线程B也将变量操作了,此时线程A是无法感知变量发生变化的,造成变量改变错误.更据以上例子我们需要解决的问题就 ...
- Python+Selenium UI自动化测试环境搭建及使用
一什么是Selenium ? Selenium 是一个浏览器自动化测试框架,它主要用于web应用程序的自动化测试,其主要特点如下:开源.免费:多平台.浏览器.多语言支持:对web页面有良好的支持:AP ...
- GitLab篇之备份还原
1. GitLab备份配置 输入以下命令,打开gitlab配置文件 [root@code-server ~]# vim /etc/gitlab/gitlab.rb 修改以下配置,gitlab有自动清理 ...
- WebGL——水波纹特效
大家好,今天我ccentry要做一个水波纹特效,我们来看看水波纹特效的做法.首先我们来看一下水波纹特效的效果是怎么样的,请看下图. 我们要做的就是类似这种纹理特效,那么我们来看看是如何制作的吧.首先鲫 ...
- SQL查询语句大全及其理解
转自:https://www.cnblogs.com/1234abcd/p/5530314.html 一.基础1.说明:创建数据库CREATE DATABASE database-name2.说明:删 ...
- [C++]typedef用法
参考:C/C++ typedef用法详解(真的很详细) 四个用途 定义一种类型的别名,而不是简单的宏替换 定义struct新对象的别名 定义和平台无关的类型 为复杂声明定义一个简单的别名 typede ...
- Navicat连接mysql报错1251
Navicat无法连接MySQL8,是因为MySQL8的方式和MySQL5的加密方式不一样导致 解决方案: 1.通过命令行进入mysql数据库: C:\Windows\system32> mys ...
- Streamr助你掌控自己的数据
博客说明 所有刊发内容均可转载但是需要注明出处. 项目简介 Streamr 致力于为世界实时数据的自由公平交换打造开源平台,并促进全球数据经济的发展.Streamr项目基于区块链技术,并向用户提供数据 ...
- java实验三实验报告
一.实验内容 1. XP基础 2. XP核心实践 3. 相关工具 二.实验过程(本次试验是在自己电脑上完成,没有使用实验楼) (一)敏捷开发与XP 1.XP是以开发符合客户需要的软件为目标而产生的一种 ...