点此看题面

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

前言

\(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. js打乱数组排序

    用到的知识点:Math.random()//用于打乱数组索引 random() 方法可返回介于 0(包含) ~ 1(不包含) 之间的一个随机数. var arr=[1,2,3,4,5,6]; for( ...

  2. 利用用阿里云API实现DDNS

    前言 之前动态域名解析是用的是腾达路由器上集成的第三方动态解析服务花生壳,解析费用一年40元.后来觉得域名前缀不好,想换掉,花生壳需要重新购买新的域名解析费用,增加1条或者2条动态解析无所谓,万一以后 ...

  3. DefinePlugin插件用法

    作者:水涛 座右铭:天行健,君子以自强不息 自白:我写博文上来蹭蹭就是干,我突然觉得我需要幽默一点了,好了,下面我们说正经的 一.官方定义: DefinePlugin DefinePlugin 允许创 ...

  4. Redis主从复制架构和Sentinel哨兵机制

    一.redis主从复制原理 redis主从同步策略:slave刚加入集群会触发一次全量同步(全量复制).全量同步之后,进行增量复制.slave优先是增量同步,如果增量同步失败会尝试从master节点进 ...

  5. HttpRunner学习4--使用正则表达式提取数据

    前言 在HttpRunner中,我们可通过extract提取数据,当响应结果为 JSON 结构,可使用 content 结合 . 运算符的方式,如 content.code,用起来十分方便,但如果响应 ...

  6. 优先队列与TopK

    一.简介 前文介绍了<最大堆>的实现,本章节在最大堆的基础上实现一个简单的优先队列.优先队列的实现本身没什么难度,所以本文我们从优先队列的场景出发介绍topK问题. 后面会持续更新数据结构 ...

  7. orleans 2.0 进阶之自定义持久化储存

    一丶简单介绍下目录结构和项目依赖,如图 二丶主要核心自定义代码 1. 添加自定义实现类 CustomProvider public class CustomProvider : IGrainStora ...

  8. 简单实用的git命令

    1.下载项目 先进入目录然后使用jit $ git clone +"url" 2.项目配置 $ composer install 3.上传项目 $ git add . () $ g ...

  9. webpack 配置babel-loader babel7

    babel 7版本配置 在webpack中 默认只能处理部分 ES6的新语法,一些更高级的ES6或ES7的语法,webpack是处理不了的这个时候就需要借助第三方的loader 来帮助webpack ...

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

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