题解-PKUWC2018 随机算法
Problem
题意简述:给定\(n\)个点的无向图,给定求最大独立集的近似算法:随机排列\(1\cdots n\),按照该排列顺序贪心构造最大独立集(即对每个点能加入独立集就加),求算法正确率
\(n\leq 20,m\leq \binom n2\)
Solution
暴力枚举应有\(10pts\)(\(n\leq 9)\)
当前状态集合为\(S\),\(0,1,2\)分别表示没访问到、访问到且在最大独立集内、访问到且未在最大独立集内,每次枚举下一个访问的节点,复杂度\(O(n3^n)\),应有\(30pts\)(\(n\leq 13\))
然而我并没有想到\(70pts\)(\(n\leq 17\))的做法,可能是\(O(n^22^n)\)?
一种玄学暴力,枚举所有最大独立集,然后\(f[S]\)来dp转移,最坏复杂度\(O(2^n\cdot 2^nn)\),但由于一个图的最大独立集没有多少,所以应该能拿一个很高的分(据学长说这个算法好像可以\(100pts\))
算了,还是来想点正经的,预估复杂度为\(O(n2^n)\),所以大致是设答案为\(f[S]\),然后枚举点进行转移
接着\(30pts\)做法,要将状态数降至\(2^n\),需要将三种状态中合并两种……然而到这我就不会了qwq
把范围展开一点,\(f[S]\)表最大独立集与与其相连的节点集合(独立集辐射范围)为\(S\)时的最大独立集大小,用\(g[S]\)计数,最终\(g[U]\)即为答案
转移就相当于每次在\(S\)里刨掉某个点与与其相连的点,好像就没了?(由于算的是期望且每个状态的步数不同,处理完每个\(g(T)\)后要将\(g(T)\)除以\(|T|\))
upd:看了题解后发现好像\(70pts\)就是我的做法再加个状态表示\(S\)的最大独立集大小(而且更显而易见),但由于每个\(S\)的最大独立集大小唯一,所以不需要这么设置
看了题解后发现有个方程更容易想,设\(S\)为独立集辐射范围(就是上面的定义),设\(w\)为当前枚举点的控制范围:
\]
Code
#include <cstdio>
const int N=21,M=1<<N,p=998244353;
int d[N],bin[N],inv[N],f[M],g[M];
int n,m,lim;
inline int pls(int&x,int y){x=x+y<p?x+y:x+y-p;}
int main(){
scanf("%d%d",&n,&m);lim=1<<n;
d[1]=bin[1]=inv[0]=inv[1]=1;
for(int i=2;i<=n;++i){
d[i]=bin[i]=bin[i-1]<<1;
inv[i]=1ll*(p-p/i)*inv[p%i]%p;
}
for(int i=m,x,y;i;--i){
scanf("%d%d",&x,&y);
d[x]|=bin[y];
d[y]|=bin[x];
}
g[0]=1;
for(int S=1,tt,s;S<lim;++S){
tt=0;
for(int i=1;i<=n;++i)
if(S&bin[i]){
++tt,s=S&(~d[i]);
if(f[S]<f[s]+1)f[S]=f[s]+1,g[S]=0;
if(f[S]==f[s]+1)pls(g[S],g[s]);
}
g[S]=1ll*g[S]*inv[tt]%p;
}
printf("%d\n",g[lim-1]);
return 0;
}
题解-PKUWC2018 随机算法的更多相关文章
- 【洛谷5492】[PKUWC2018] 随机算法(状压DP)
点此看题面 大致题意: 用随机算法求一张图的最大独立集:每次随机一个排列,从前到后枚举排列中的点,如果当前点加入点集中依然是独立集,就将当前点加入点集中,最终得到的点集就是最大独立集.求这个随机算法的 ...
- [PKUWC2018]随机算法
题意:https://loj.ac/problem/2540 给定一个图(n<=20),定义一个求最大独立集的随机化算法 产生一个排列,依次加入,能加入就加入 求得到最大独立集的概率 loj25 ...
- LG5492 [PKUWC2018]随机算法
题意 有一种贪心求最大独立集的算法: 随机一个排列 按顺序加入独立集,如果一个点能加入,就加入\({S}\) 给出一张图,问得出正确答案的概率. \(n \leq 20\) 传送门 思路 用 \(dp ...
- 题解-PKUWC2018 随机游走
Problem loj2542 题意:一棵 \(n\) 个结点的树,从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去,询问走完一个集合 \(S\)的期望时间,多组询问 \(n\le ...
- LOJ2540 [PKUWC2018] 随机算法 【状压DP】
题目分析: 听说这题考场上能被$ O(4^n) $的暴力水过,难不成出题人是毕姥爷? 首先思考一个显而易见的$ O(n^2*2^n) $的暴力DP.一般的DP都是考虑最近的加入了哪个点,然后删除后递归 ...
- LOJ2540 PKUWC2018 随机算法 状压DP
传送门 两种$DP$: ①$f_{i,j}$表示前$i$次选择,最大独立集为$j$时达到最大独立集的方案总数,转移:$a.f_{i,j}+=f_{i+1,j+2^k}$(保证$k$加入后符合条件):$ ...
- [LOJ2540] [PKUWC2018] 随机算法
题目链接 LOJ:https://loj.ac/problem/2540 Solution 写的时候脑子不太清醒码了好长然后时间\(LOJ\)垫底... 反正随便状压\(dp\)一下就好了,设\(f[ ...
- [LOJ#2540][PKUWC2018]随机算法(概率DP)
场上数据很水,比较暴力的做法都可以过90分以上,下面说几个做法. 1. 暴力枚举所有最大独立集,对每个独立集分别DP.复杂度玄学,但是由于最大独立集并不多,所以可以拿90. 2. dp[S][k]表示 ...
- 【LOJ2540】「PKUWC2018」随机算法
题意 题面 给一个 \(n\) 个点 \(m\) 条边的无向图.考虑如下求独立集的随机算法:随机一个排列并按顺序加点.如果当前点能加入独立集就加入,否则不加入.求该算法能求出最大独立集的概率. \(n ...
随机推荐
- 关于Django启动创建测试库的问题
最近项目迁移到别的机器上进行开发,启动Django的时候,有如下提示: Creating test database for alias 'default' 其实这个可能是在Django启动按钮的设置 ...
- 插入排序_JAVA
public class Main { public static void main(String[] args) { int[] A = { 6, 4, 3, 5, 6, 2 }; for (in ...
- 02-Unity深入浅出(二)
一. Unity声明周期 Unity容器为我们提供了6种生命周期,便于我们根据项目需求来选择使用. (1). 瞬时.默认省略即为瞬时,无论单线程还是多线程,每次都重新创建对象.new Transien ...
- 细说shiro之五:在spring框架中集成shiro
官网:https://shiro.apache.org/ 1. 下载在Maven项目中的依赖配置如下: <!-- shiro配置 --> <dependency> <gr ...
- Socket编程 (一)
<<Linux 网络编程>>摘要 注意: 其中的大部分成员是网络字节序(大端字节序); 编程: 服务器先要做的事情: socket() 初始化Socket bind() 绑定本 ...
- SQL Server进阶(六)表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数
概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...
- 嫁给程序员的好处,你get到了吗?
首先,我们要知道,什么是程序员?程序员是做什么的? "程序员(英文Programmer)是从事程序开发.维护的专业人员.一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚, ...
- 【游记】THUWC2018踹线记
Day1. 早上九点多报道,然后就是试机.一开始有一些懵,没看清门外的通知,操作起来各种懵逼.不过提前适应过了在Linux下面编程,所以问题不大.调了gedit的界面,试了一下对拍,敲了一道试机题,然 ...
- win7, ubuntu双系统,重装win7后,修复引导
参考: http://blog.csdn.net/abcsunl/article/details/72875983 http://blog.csdn.net/davied9/article/detai ...
- Python之List列表的循环和切片
一.循环(for):输出列表中的每一个元素 stus=['杨静','王志华','王银梅','乔美玲'] #一个个输出列表元素 for s in stus: print('s 是 %s'%s) s 是 ...