JZOJ1321. 灯
来源:互联网 发布:海尔软件收入 编辑:程序博客网 时间:2024/04/29 21:26
Description
贝希和她的闺密们在她们的牛棚中玩游戏。但是天不从人愿,突然,牛棚的电源跳闸了,所有的灯都被关闭了。贝希是一个很胆小的女生,在伸手不见拇指的无尽的黑暗中,她感到惊恐,痛苦与绝望。她希望您能够帮帮她,把所有的灯都给重新开起来!她才能继续快乐地跟她的闺密们继续玩游戏!
牛棚中一共有N(1 <= N <= 35)盏灯,编号为1到N。这些灯被置于一个非常复杂的网络之中。有M(1 <= M <= 595)条很神奇的无向边,每条边连接两盏灯。
每盏灯上面都带有一个开关。当按下某一盏灯的开关的时候,这盏灯本身,还有所有有边连向这盏灯的灯的状态都会被改变。状态改变指的是:当一盏灯是开着的时候,这盏灯被关掉;当一盏灯是关着的时候,这盏灯被打开。
问最少要按下多少个开关,才能把所有的灯都给重新打开。
数据保证至少有一种按开关的方案,使得所有的灯都被重新打开。
分析
看到这里的n很小,只有35,就会想到暴力,
可是如果枚举每一个开关的状态,就是
这是一个不可以接受的复杂度。
我们就可以考虑折半搜索。
就拿35盏灯来举例
我们将开关分成第1~17和第18~35两个部分。
先用
也就是说我们知道某个全局灯亮的情况对应着需要使用多少个1~17的开关。
这些提前求出了的东西就用一个哈希表存着。
接下来就考虑第18~35个开关,
同样我们枚举每个开关的开与关,也可以知道此时全局灯的亮的情况。
将这些情况与之前求出的状态在哈希表中对应,即可求出答案。
code
#include <cstdio>#include <algorithm>#include <cstring>#include <string.h>#include <cmath>#include <math.h>#define N 40#define mo 123454321#define ll long longusing namespace std;int n,m,x,y,d;int tot,next[N*N],a[N*N],b[N],f[N],g[mo],ans;ll sum,z[N],h[mo];char ch;void read(int &n){ n=0; ch=getchar(); while((ch<'0' || ch>'9') && ch!='-')ch=getchar(); int w=1; if(ch=='-')w=-1,ch=getchar(); while('0'<=ch && ch<='9')n=n*10+ch-'0',ch=getchar(); n*=w;}void ins(int x,int y){ next[++tot]=b[x]; a[tot]=y; b[x]=tot;}void add(int x){ f[x]=1-f[x]; for(int i=b[x];i;i=next[i]) f[a[i]]=1-f[a[i]];}void hs(ll s,int y){ int x=s%mo; while(h[x]!=0 && h[x]!=s)x=(x+1)%mo; g[x]=min(g[x],y); h[x]=s;}int find(ll s){ int x=s%mo; while(h[x]!=0 && h[x]!=s)x=(x+1)%mo; if(h[x]==s)return g[x];else return mo;}void pre(int x,int s){ if(x>n) { sum=0; for(int i=1;i<=n;i++) sum=sum+f[i]*z[i-1]; hs(sum,s); return; } add(x); pre(x+1,s+1); add(x); pre(x+1,s);}void dg(int x,int s){ if(s>=ans)return; if(x>d) { sum=0; for(int i=1;i<=n;i++) sum=sum+z[i-1]-f[i]*z[i-1]; ans=min(ans,find(sum)+s); return; } add(x); dg(x+1,s+1); add(x); dg(x+1,s);}int main(){ z[0]=1; for(int i=1;i<N;i++) z[i]=z[i-1]*2; read(n);read(m); for(int i=1;i<=m;i++) read(x),read(y),ins(x,y),ins(y,x); d=n/2; memset(g,127,sizeof(g)); pre(d+1,0); memset(f,0,sizeof(f)); ans=2147483647; dg(1,0); printf("%d",ans);}
阅读全文
0 0
- JZOJ1321. 灯
- Jzoj1321 灯
- 灯
- 灯
- 灯。。。
- 灯。。。
- 灯
- 闪烁灯
- 跑马灯
- 流水灯
- 跑马灯
- 控制灯
- 循环灯
- 闪烁灯
- 流水灯
- 跑马灯
- 流水灯
- 流水灯
- 开发经验总结
- lstm 做 文本的情感分析
- JavaWeb学习总结(二十一)——JavaWeb的两种开发模式
- 第n个丑数
- LeetCode 304 Range Sum Query 2D
- JZOJ1321. 灯
- 编译过程知识点-------笔记
- TCP协议中的三次握手和四次挥手(图解)
- The import java.util.TreeSet conflicts with a type defined in the same file
- CSS display:none和visibility:hidden的区别
- Servlet的请求转发和重定向转发
- JavaWeb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册
- java判断字符串是否为数字或中文或字母
- Android内存优化之OOM