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 ...
随机推荐
- c# thread pause example
some times we need pause thread to do some additional job: c# thread pause example as below: 1. crea ...
- 20155238 实验四 Android程序设计
Android 安装Android Studio 按照教程依次完成安装步骤.安装所存的相应文件夹必须纯英文,不能出现特殊字符. 32位系统和64位系统是同一个安装文件.启动程序中32位与64位都有.根 ...
- 20155334 网络对抗PC平台逆向破解(二)
注入Shellcode并运行攻击 shellcode就是一段机器指令(code) 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe) ...
- Hibernate一对多关联关系保存时的探究
在以前使用hibernate时,经常对保存存在关联关系的对象时,不确定是否能保存成功. 因此,特意对一对多关系的2个对象进行实践. 一.pojo类和配置文件的准备 这里有一点提前 ...
- Python+Selenium爬取动态加载页面(2)
注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...
- POJ1035&&POJ3080&&POJ1936
字符串处理专题,很早就写好了然而忘记写blog了 1035 题意:给你一些单词作为字典.然后让你查找一些单词.对于每个单词,如果在字典中就输出它.否则输出所有它通过删除||增加||替换一个字符能得到的 ...
- 阿里云Redis外网转发访问
1.前提条件 如果您需要从本地 PC 端访问 Redis 实例进行数据操作,可以通过在 ECS 上配置端口映射或者端口转发实现.但必须符合以下前提条件: 若 Redis 实例属于专有网络(VPC),E ...
- Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述
目录 引言 概要 Query and filter context Match All Query 全文查询 Full text queries 小结 参考文档 引言 虽然之前做过 elasticse ...
- OLEDB数据源和目标组件
在SSIS工程的开发过程中,OLEDB 数据源和目标组件是最常用的数据流组件.从功能上讲,OLEDB 数据源组件用于从OLEDB 提供者(Provider)中获取数据,传递给下游组件,OLEDB提供者 ...
- cadence allegro 封装原点修改
打开 dra文件后 在菜单栏 setup - change drawing origin 在命令栏输入 新的参考点位置 如想更改新坐标位置为 1,2 .输入 x 1 2