点此看题面

大致题意: 用随机算法求一张图的最大独立集:每次随机一个排列,从前到后枚举排列中的点,如果当前点加入点集中依然是独立集,就将当前点加入点集中,最终得到的点集就是最大独立集。求这个随机算法的正确率。

前言

\(PKUWC\)的题目就是妙啊。

题目很神仙,但看完题解后就很简单了,可这种东西像我这般蒟蒻根本想不到啊......

状压\(DP\)

设\(f_{i,j}\)表示当前已考虑过点集\(i\),最大独立集为\(j\)的方案数。

每次我们枚举一个不在点集中的点\(k\),设与其相邻的点的集合为\(a_k\)。

则,如果我们要选择点\(k\)作为独立集中的点,那么与其相邻的点就不能再选择,方便起见,我们直接把\(a_k\)算作考虑过的点。

即,对于\(f_{i,j}\)和\(k\),我们可以转移到\(f_{i|2^{k-1}|a_k,j+1}\)。

注,这里之所以是\(2^{k-1}\),因为我习惯用二进制下第\(x-1\)位来表示第\(x\)个数是否被选择。

不难发现,根据我们的转移方式,由于\(k\)不在点集中,所以点集中被选作独立集中的点的点一定不与\(k\)相邻,否则在那个点被选作独立集中的点时就已经把\(k\)加入点集了,因此必然\(j\)可以加\(1\)。

然后我们考虑,在这一步转移下,\(k\)肯定是要直接加入点集中的,即必然在剩下的点中名列第一,它的位置是固定的。

而对于那些与\(k\)相邻、又不在点集\(i\)中的点(即:\(a_k-(i\&a_k)\)),它们可以在\(k\)之后的任意一个位置(共有\(n-g_i-1\)个位置,其中\(g_i\)代表点集\(i\)中的点,\(1\)代表点\(k\))加入点集,因此方案数为\(A_{n-g_i-1}^{g_{a_k-(i\& a_k)}}\)。

其中,\(A\)表示排列数,\(A_n^m=\frac{n!}{(n-m)!}\);\(g_i\)表示点集\(i\)中点的个数。

所以:\(f_{i|2^{k-1}|a_k,j+1}+=f_{i,j}\cdot A_{n-g_i-1}^{g_{a_k-(i\&a_k)}}\)。

由于求概率,而我们求的是方案数,所以最后的答案就是:\(\frac{f_{2^n-1,w}}{n!}\),其中\(w\)表示最大独立集的大小。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 20
#define X 998244353
#define A(x,y) (1LL*Fac[x]*IFac[(x)-(y)]%X)
using namespace std;
int n,m,a[N+5],f[1<<N][N+5],g[1<<N],Fac[N+5],IFac[N+5];
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
int main()
{
RI i,x,y;for(scanf("%d%d",&n,&m),i=1;i<=m;++i) scanf("%d%d",&x,&y),a[x]|=1<<y-1,a[y]|=1<<x-1;//读入,记录相邻点
for(Fac[0]=i=1;i<=N;++i) Fac[i]=1LL*Fac[i-1]*i%X;//预处理阶乘
for(IFac[N]=Qpow(Fac[N],X-2),i=N-1;~i;--i) IFac[i]=1LL*IFac[i+1]*(i+1)%X;//预处理阶乘逆元
RI j,k,t=1<<n;for(i=0;i^t;++i) g[i]=g[i>>1]+(i&1);for(f[0][0]=1,i=0;i^t;++i)//枚举点集
{
for(j=0;j<=g[i];++j) for(k=1;k<=n;++k) !((i>>k-1)&1)&&//一定要选择不在点集中的点
(f[i|(1<<k-1)|a[k]][j+1]=(1LL*f[i][j]*A(n-g[i]-1,g[a[k]-(i&a[k])])+f[i|(1<<k-1)|a[k]][j+1])%X);//转移
}
for(i=n;!f[t-1][i];--i);return printf("%d",1LL*f[t-1][i]*IFac[n]%X),0;//求最大独立集点数,然后输出答案
}

【洛谷5492】[PKUWC2018] 随机算法(状压DP)的更多相关文章

  1. LOJ2540 PKUWC2018 随机算法 状压DP

    传送门 两种$DP$: ①$f_{i,j}$表示前$i$次选择,最大独立集为$j$时达到最大独立集的方案总数,转移:$a.f_{i,j}+=f_{i+1,j+2^k}$(保证$k$加入后符合条件):$ ...

  2. 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)

    洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...

  3. 洛谷 P1278 单词游戏 【状压dp】

    题目描述 Io和Ao在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何一个单词开始. 任何单词禁止说两遍,游戏中只 ...

  4. 洛谷P2051 [AHOI2009] 中国象棋(状压dp)

    题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...

  5. 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]

    题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...

  6. 洛谷P2761 软件补丁问题(状压DP,SPFA)

    题意 描述不清... Sol 网络流24题里面怎么会有状压dp?? 真是狗血,不过还是简单吧. 直接用$f[sta]$表示当前状态为$sta$时的最小花费 转移的时候枚举一下哪一个补丁可以搞这个状态 ...

  7. 洛谷P2831 愤怒的小鸟——贪心?状压DP

    题目:https://www.luogu.org/problemnew/show/P2831 一开始想 n^3 贪心来着: 先按 x 排个序,那么第一个不就一定要打了么? 在枚举后面某一个,和它形成一 ...

  8. 洛谷$P$3160 局部极小值 $[CQOI2012]$ 状压$dp$

    正解:状压$dp$ 解题报告: 传送门! 什么神仙题昂,,,反正我是没有想到$dp$的呢$kk$,,,还是太菜了$QAQ$ 首先看数据范围,一个4×7的方格,不难想到最多有8个局部极小值,过于显然懒得 ...

  9. 洛谷P2761 软件补丁问题 [状压DP,SPFA]

    题目传送门 软件补丁问题 题目描述 T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放了一批共 m 个补丁程序.每一个补丁程序都有其特定的适用环境,某个补丁只有在软件中包含某些错误而同时又 ...

  10. 洛谷 P2473 [SCOI2008]奖励关(状压dp+期望)

    题面 luogu 题解 \(n \leq 15\) 状压 \(f[i][S]\)表示第\(i\)轮,吃过的集合为\(S\) 正着转移好像有点复杂 考虑逆推转移(正着转移应该也行) \(f[i][S]\ ...

随机推荐

  1. 毕业半年,买了一台MacBook Pro

    前言 只有光头才能变强. 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 毕业半年,给自己买了一台MacBookPro 1 ...

  2. java虚拟机栈 相关操作

    针对JVM虚拟栈 和栈帧的操作 虚拟机栈: 栈元素是栈帧.方法调用,栈帧入栈,反之出栈. 栈帧:一个方法的运行空间. 1.局部变量表:方法定义的局部变量.方法的参数存在该表. 实例方法中有个隐含参数“ ...

  3. java基础篇一

    引言 本人系南京一小小学校的大三小小菜鸟,三年来学了很多杂七杂八的,也荒废了大量的时间,马上就要秋招了,之前也看了不少面试题,备选了一些简单的项目,看了不知多少本的几百页厚的各种知识的pdf电子书,发 ...

  4. Java-50个关键字

    关键字 (50个,包含2个保留字)和特殊值(3个)一.基本数据类型相关关键字(8个) 1.关键字介绍(1)byte:单字节类型(2)short:短整型(3)int:整型(4)long:长整型(5)ch ...

  5. Racket 命令行方式安装 collection

    最近在学习 SICP,里面用的 Lisp 系列的 Scheme.OS X 上要配置Scheme环境. Racket 完整的包要 110 M,mini 版只要10M.我只需要简单的命令行操作,显然选mi ...

  6. 我如何通过K8S开发认证(CKAD)考试

    题记:笔者最近经过3个多月的空余时间准备,终于通过了K8S开发认证(CKAD)的考试,在这里简单给大家分享一下经验. 一,先科普下CKAD 众所周知,Kubernetes在容器编排器大战中脱颖而出后, ...

  7. Eureka 入门,带视频

    疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 架构师成长+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 前言 Crazy ...

  8. 网络爬虫引发的问题及robots协议

    一.网络爬虫的尺寸 1.以爬取网页,玩转网页为目的进行小规模,数据量小对爬取速度不敏感的可以使用request库实现功能(占90%) 2.以爬取网站或爬取系列网站为目的,比如说获取一个或多个旅游网站的 ...

  9. 【译】ModSecurity

    Preface 本篇译ModSecurity 主页的自身介绍. ModSecurity is an open source, cross-platform web application firewa ...

  10. CURL命令学习一

    每天学习一点点.... 直接获取页面数据: curl http://www.xxx.com/[可以指定具体的路径获取某个文件] 用户名(密码): curl -u username http://www ...