bzoj2560 串珠子
Description
现在已知所有珠子互不相同,用整数1到n编号。对于第i个珠子和第j个珠子,可以选择不用绳子连接,或者在ci,j根不同颜色的绳子中选择一根将它们连接。如果把珠子看作点,把绳子看作边,将所有珠子连成一个整体即为所有点构成一个连通图。特别地,珠子不能和自己连接。
铭铭希望知道总共有多少种不同的方案将所有珠子连成一个整体。由于答案可能很大,因此只需输出答案对1000000007取模的结果。
Input
标准输入。输入第一行包含一个正整数n,表示珠子的个数。接下来n行,每行包含n个非负整数,用空格隔开。这n行中,第i行第j个数为ci,j。
Output
标准输出。输出一行一个整数,为连接方案数对1000000007取模的结果。
Sample Input
0 2 3
2 0 4
3 4 0
Sample Output
HINT
对于100%的数据,n为正整数,所有的ci,j为非负整数且不超过1000000007。保证ci,j=cj,i。每组数据的n值如下表所示。
编号 1 2 3 4 5 6 7 8 9 10
n 8 9 9 10 11 12 13 14 15 16
正解:状压dp。
这道题很玄学,感觉还是懵懵懂懂。。今天的出题人太丧病了。。
考虑状压dp,我们把n个点压成二进制数。
我们设两个数组,g[s]表示s状态下的所有情况,即s状态下的点两两之间任意连边(包括不连边的情况),f[s]表示s状态下的合法情况,即使得s状态下所有点连通的合法情况。那么答案就是f[2^n-1]。
然后我们可以很容易地求出g[s],我们求出g[s]后,考虑如何求f[s],f[s]就是g[s]减去所有的不合法情况。那么我们可以枚举s的所有子集,设子集为i,那么不合法的情况就是g[i]*f[s^i],我们减去这些情况,就能求出f[s]了。
枚举子集很玄学。。我反正不知道这是怎么回事,看了网上大神的博客。。
http://www.cnblogs.com/jffifa/archive/2012/01/16/2323999.html
for (int x = S; x; x = (x-)&S)
大概是这个鬼东西。。大神的证明:
x = (x-1)&S实际上是把S中的0全部忽略,并不断减1的结果,比如S=1011,则x分别为:1011, 1010, 1001, 1000, 0011, 0010, 0001。忽略S中第二位的0其实就是111, 110, 101, 100, 011, 010, 001。
称S中的1所在位为有效位,0所在位为无效位,则x中的无效位必为0,有效位为0或1,比如S=1011,x=1001(有效位加下划线)。-1就是加上-1补码1111…,可以想成把无效位的1先加上去,比如x=1001变成1101,再加有效位的1。由于无效位加完肯定是1,会把有效位的进位“传递”下去,然后再位与S使得无效位变成0,实际就相当于有效位加上1111…,也就是有效位-1。
于是我们就能解决这题了。其实我还没搞懂为什么要这么搞。
//It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1<<30)
#define il inline
#define RG register
#define ll long long
#define rhl 1000000007
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; ll f[<<],g[<<],bin[],a[][],n; il int gi(){
RG int x=,q=; RG char ch=getchar(); while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar(); while (ch>='' && ch<='') x=x*+ch-,ch=getchar(); return q*x;
} il void work(){
n=gi(),bin[]=;
for (RG int i=;i<=n;++i)
for (RG int j=;j<=n;++j) a[i][j]=gi();
for (RG int i=;i<=n;++i) bin[i]=bin[i-]<<;
for (RG int k=;k<bin[n];++k){
f[k]=;
for (RG int i=;i<n;++i) if (k&bin[i-])
for (RG int j=i+;j<=n;++j) if (k&bin[j-]) f[k]=f[k]*(a[i][j]+)%rhl;
g[k]=f[k]; RG int i=k^(k&-k); //枚举真子集?!
for (RG int j=i;j;j=(j-)&i) f[k]=(f[k]-g[j]*f[k^j]%rhl+rhl)%rhl;
}
printf("%lld\n",f[bin[n]-]); return;
} int main(){
File("bunch");
work();
return ;
}
bzoj2560 串珠子的更多相关文章
- bzoj2560串珠子 状压dp+容斥(?)
2560: 串珠子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 515 Solved: 348[Submit][Status][Discuss] ...
- bzoj2560串珠子(子集dp)
铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子.现在铭铭想用绳子把所有的珠子连接成一个整体. 现在已知所有珠子互不相同,用整数1到n编号.对于第i个珠子和第j个珠子,可以选择不用绳子连接,或者在ci, ...
- 题解-bzoj2560 串珠子
刚被教练数落了一通,心情不好,来写篇题解 Problem bzoj2560 题目简述:给定\(n\)个点的,每两个点\(i,j\)之间有\(c_{i,j}\)条直接相连的路(其中只能选一条或不选),问 ...
- BZOJ2560串珠子
/* 很清新的一道题(相比上一道题) g[S]表示该 S集合中胡乱连的所有方案数, f[S] 表示S集合的答案 那么F[S] 等于G[S]减去不合法的部分方案 不合法的方案就枚举合法的部分就好了 g[ ...
- 2019.02.09 bzoj2560: 串珠子(状压dp+简单容斥)
传送门 题意简述:nnn个点的带边权无向图,定义一个图的权值是所有边的积,问所有nnn个点都连通的子图的权值之和. 思路: fif_ifi表示保证集合iii中所有点都连通其余点随意的方案数. gig ...
- 【题解】Bzoj2560串珠子
挺强的……容斥+状压DP.首先想到如果可以求出f[k],f[k]代表联通状态为k的情况下的合法方案数,则f[k] = g[k] - 非法方案数.g[k]为总的方案数,这是容易求得的.那么非法方案数我们 ...
- bzoj2560串珠子——子集DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2560 转载: 很明显的状压dp 一开始写的dp可能会出现重复统计的情况 而且难以去重 假设 ...
- [BZOJ2560]串珠子:状压DP+容斥原理
分析 为什么我去年6月做过这道题啊,估计当时抄的题解. 具体做法就是令\(f[S]\)表示保证连通点集\(S\)的方案数,\(g[S]\)表示不保证连通点集\(S\)的方案数. 容易想到: \[g[S ...
- bzoj2560 串珠子 状压DP
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2560 题解 大概是这类关于无向图的联通性计数的套路了. 一开始我想的是这样的,考虑容斥,那么就 ...
随机推荐
- MySQL相关信息(二)
1.修改MySQL提示符 (1)连接客户端时通过参数指定 shell>mysql -u root -p --prompt 提示符 C:\Users\Administrator>mysql ...
- C#与Java区别(一)
最近学了点java,总结了一些和c#的语法区别,欢迎大家指点和补充,如下: 1.java支持跨平台,当然.net core现在也支持. 2.java中用package,c#中用namespace定义空 ...
- Spring还使用基于 JSR-250 注释,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释
@PostConstruct 和 @PreDestroy 注释: 你可以使用 @PostConstruct 注释作为初始化回调函数的一个替代,@PreDestroy 注释作为销毁回调函数的一个替代,其 ...
- 有个程序猿要去当CEO了:(一)事情始末
事情大概是这样的: 去年年底,我从原公司离职,原因大概是公司绩效不好,呆着也没意思. 后来听说,年终结算遣散了所有人. 今年年初的时候,前老板又找上我,说希望能和我再合作. 起先是想分我一部分干股,让 ...
- VC++中解决“在查找预编译头使用时跳过”的方法
Visual C++ Concepts: Building a C/C++ ProgramCompiler Warning (level 1) C4627Error Message": sk ...
- 什么是https
我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取.所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议. HTTPS简介 HTTPS其实是有两部分组成:HTTP + SSL ...
- 任务调度之集群(基于Quartz.net)
上一篇我们完成了任务调度的持久化,传送门:任务调度之持久化(基于Quartz.net) 这篇我们来完成Quartz.net的一个比较优秀的功能,即集群:集群可以提高任务调度服务的容灾性, 当一个节点宕 ...
- 当在浏览器地址栏里输入URL后会发生什么事情
其实这个很多大神已经说的很多了.但是为了自己更好的理解,在自己所接触的层面上,重新对自己讲解一下.当然,这是站在一个前端开发者的角度上来看问题的. 说说一次HTTP完整事务的过程 输入URL 浏览器从 ...
- (转)Java线程面试题 Top 50
原文链接:http://www.importnew.com/12773.html 本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎加入Java小组.转载请参见文章末 ...
- poj 3070 Fibonacci (矩阵快速幂乘/模板)
题意:给你一个n,输出Fibonacci (n)%10000的结果 思路:裸矩阵快速幂乘,直接套模板 代码: #include <cstdio> #include <cstring& ...