LOJ#2540 随机算法
题意:给定图,随机一个排列,依次加点,如果加点之后不是独立集就不加。求最后得到一个最大独立集的概率。
解:就是求有多少个排列可以加出最大独立集。
显然有一个3n的状压DP,0表示没加,1表示没加上,2表示加上了。
转移的时候枚举下一个加哪个点即可。这样有30分。
然后还是过不了的。考虑怎么压成二进制。我们可以用1表示这个点不能加(与某个加入的点相邻或者已经加入),0表示这个点可以加。
这样会损失一个信息,你就不知道当前独立集多大。所以再开一维表示独立集大小。
每次转移的时候考虑加哪一个点。顺便把它相邻的点也加上。注意它相邻的点加入的时候有顺序。具体来说,我们之前的状态中如果有x个点,那么就还有n - x个空位。而其中最前面的一个空位肯定是你主动加进去的点。所以现在要在n - x - 1个空位中放进被动加进去的点。这就是一个排列数。
然后就有了一个n2n的DP了。注意预处理出与一个点相邻的点和一个状态中点的个数。
#include <cstdio> typedef long long LL;
const int N = ;
const LL MO = ; struct Edge {
int nex, v;
}edge[N * N * ]; int top; int n, e[N], cnt[ << ], nb[N];
LL f[N][ << ], nn[N], inv[N], invn[N];
bool vis[N]; inline void add(int x, int y) {
top++;
edge[top].v = y;
edge[top].nex = e[x];
e[x] = top;
return;
} inline void out(int x) {
for(int i = ; i < n; i++) {
printf("%d", (x >> i) & );
}
return;
} inline LL C(int n, int m) {
return nn[n] * invn[m] % MO * invn[n - m] % MO;
}
inline LL P(int n, int m) {
if(m > n) {
return ;
}
return nn[n] * invn[n - m] % MO;
} int main() {
int m;
scanf("%d%d", &n, &m);
for(int i = , x, y; i <= m; i++) {
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
int lm = ( << n);
for(int s = ; s < lm; s++) {
cnt[s] = + cnt[(s - (s & (-s))) >> ];
}
for(int x = ; x < n; x++) {
nb[x] = << x;
for(int i = e[x + ]; i; i = edge[i].nex) {
int y = edge[i].v - ;
nb[x] |= ( << y);
}
}
nn[] = inv[] = invn[] = ;
nn[] = inv[] = invn[] = ;
for(int i = ; i <= n; i++) {
nn[i] = nn[i - ] * i % MO;
inv[i] = inv[MO % i] * (MO - MO / i) % MO;
invn[i] = invn[i - ] * inv[i] % MO;
} int ans = ;
LL sum = ;
f[][] = vis[] = ;
for(int i = ; i <= n && vis[i]; i++) {
for(int s = ; s < lm; s++) {
// f[i][s]
if(!f[i][s]) {
continue;
}
//printf("f %d ", i); out(s); printf(" = %lld \n", f[i][s]);
if(i > ans) {
ans = i;
sum = f[i][s];
}
else if(i == ans) {
sum = (sum + f[i][s]) % MO;
}
for(int j = ; j < n; j++) {
if((s >> j) & ) {
continue;
}
int t = s | nb[j];
// f[i + 1][t]
(f[i + ][t] += f[i][s] * P(n - cnt[s] - , cnt[t] - cnt[s] - ) % MO) %= MO;
vis[i + ] = ;
//printf("f %d ", i + 1); out(t); printf(" += f %d ", i); out(s); printf(" * %lld \n", P(n - cnt[s] - 1, cnt[t] - cnt[s] - 1));
}
}
} printf("%lld\n", sum * invn[n] % MO);
//printf("%d %lld \n", ans, sum);
return ;
}
AC代码
LOJ#2540 随机算法的更多相关文章
- LOJ #2540. 「PKUWC 2018」随机算法(概率dp)
题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...
- [PKUWC2018]随机算法
题意:https://loj.ac/problem/2540 给定一个图(n<=20),定义一个求最大独立集的随机化算法 产生一个排列,依次加入,能加入就加入 求得到最大独立集的概率 loj25 ...
- 微信红包中使用的技术:AA收款+随机算法
除夕夜你领到红包了吗?有的说“我领了好几K!”“我领了几W!” 土豪何其多,苦逼也不少!有的说“我出来工作了,没压岁钱了,还要发红包”.那您有去抢微信红包吗?微信群中抢“新年红包”春节爆红.618微信 ...
- POJ 3318 Matrix Multiplication(随机算法)
题目链接 随机算法使劲水...srand((unsigned)time(0))比srand(NULL)靠谱很多,可能是更加随机. #include <cstdio> #include &l ...
- 抽奖随机算法的技术探讨与C#实现
一.模拟客户需求 1.1 客户A需求:要求每次都按照下图的概率随机,数量不限,每个用户只能抽一次,抽奖结果的分布与抽奖概率近似. 1.2 客户B需求:固定奖项10个,抽奖次数不限,每个用户只能抽一次, ...
- hdu 4712 (随机算法)
第一次听说随机算法,在给的n组数据间随机取两个组比较,当随机次数达到一定量时,答案就出来了. #include<stdio.h> #include<stdlib.h> #inc ...
- 权重随机算法的java实现
一.概述 平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的.如广告投放.负载均衡等. 如有4个元素A.B.C.D,权重分别为1.2.3.4,随机结果 ...
- hdu 4712 Hamming Distance ( 随机算法混过了 )
Hamming Distance Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- HDU4712+随机算法
随机算法 求n个20位的2进制串的MinDist. Dist:两个串的异或结果中1的个数 /* 随机算法 */ #include<algorithm> #include<iostre ...
随机推荐
- 20155334 《网络攻防》Exp4 恶意代码分析
<网络攻防>Exp4 恶意代码分析 一.实验问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监 ...
- 【WPF】两则动画效果
原文:[WPF]两则动画效果 引言 利用WPF的动画可以轻而易举的实现各种各样的特效,如擦除,滑动进入等,先看两个效果图 第一个效果 这个动画其实利用了OpacityMask和LinearGradie ...
- EJB开发第一期---EJB开发配置
一.EJB 3.0简介 1.1 什么是EJB Enterprise JavaBeans是一个用于分布式业务应用的标准服务端组件模型.采用Enterprise JavaBeans架构编写的应用是可伸缩的 ...
- 【LG4248】[AHOI2013]差异
[LG4248][AHOI2013]差异 题面 洛谷 题解 后缀数组版做法戳我 我们将原串\(reverse\),根据后缀自动机的性质,两个后缀的\(lcp\)一定是我们在反串后两个前缀的\(lca\ ...
- 51nod 小朋友的笑话
链接 分析: 每次操作把以前没有出现这个数的设为1,有这个数的设为0.首先将当前区间设为1,考虑有set维护这个颜色出现的区间,然后把所有与当前区间相交的拿出来,修改为0. 复杂度?每次操作的线段只会 ...
- 利用JS实现一个简单的二级联动菜单
前几天在看js的相关内容,所以就简单写了一个二级联动菜单.分享一下. <!DOCTYPE html> <html lang="en"> <head&g ...
- Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法
一.背景介绍 强连通分量是有向图中的一个子图,在该子图中,所有的节点都可以沿着某条路径访问其他节点.强连通性是一种非常重要的等价抽象,因为它满足 自反性:顶点V和它本身是强连通的 对称性:如果顶点V和 ...
- Microsoft Dynamics CRM 常用JS语法(已转成vs2017语法提示)
背景 最近接触到Microsoft Dynamics CRM的开发.前端js是必不可少的部分,奈何没有一个语法提示,点不出来后续的语句. 在vscode上面搜索插件的时候发现,有一个大神写的插件htt ...
- identityServer4 中的概念(Scope,claim)
在IdentityServer中好多地方出现这几个词,这单词的解释也有好多大神解释过: chaim: ASP.NET Core 之 Identity 入门(一),这个是asp.net identity ...
- OpenGL:使用顶点数组法绘制正六面体
在今天的opengl的课程以及实验中,我们学习了如何使用顶点数组的方法来绘制图形,但相信还有很多同学对它的实际使用方法不太了解,我们就用我们今天实验课上的实例来简单讲解一下 题目及要求 绘制一个正六面 ...