Description

题库链接

给定一张有 \(n\) 个点 \(m\) 条边的无向图,生成 \(1\sim n\) 的全排列,假设一个排列是 \(p\) , \(S\) 是当前最大独立集;如果 \(S\cup {p_i}\) 是独立集就令 \(S=S\cup {p_i}\) ;

求这 \(n!\) 个独立集为最大独立集的概率,答案对 \(998244353\) 取模。

\(1\leq n\leq 20\)

Solution

我们记 \(mx_{i,j}\) 表示排好序的点以及这些点周围的的点的状态为 \(i\) ,有 \(j\) 个点还未选入序列,其中的最大独立集内点数最大值; \(f_{i,j}\) 表示该状态下的排列个数。

转移就是考虑这一位是将状态内的未选择的点排入排列内或者是重新在状态外再选点。

时间复杂度是 \(O(2^n\times n^2)\) ,并不满。

Code

#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
using namespace std;
const int N = 20+5, SIZE = (1<<20)+5, yzh = 998244353; int n, m, u, v, sta[N], bin[N], f[SIZE][N], mx[SIZE][N], cnt[SIZE], inv[N]; void work() {
scanf("%d%d", &n, &m); bin[0] = inv[1]= 1;
for (int i = 1; i <= n; i++) bin[i] = bin[i-1]<<1;
for (int i = 2; i <= n; i++) inv[i] = -1ll*yzh/i*inv[yzh%i]%yzh;
for (int i = 1; i <= bin[n]; i++) cnt[i] = cnt[i-lowbit(i)]+1;
for (int i = 1; i <= m; i++) {
scanf("%d%d", &u, &v);
sta[u-1] |= bin[v-1]; sta[v-1] |= bin[u-1];
}
f[0][0] = 1;
for (int i = 0; i < bin[n]; i++)
for (int j = n; j >= 0; j--)
if (f[i][j]) {
if (j) {
if (mx[i][j-1] == mx[i][j]) (f[i][j-1] += 1ll*f[i][j]*j%yzh) %= yzh;
else if (mx[i][j-1] < mx[i][j]) mx[i][j-1] = mx[i][j], f[i][j-1] = 1ll*f[i][j]*j%yzh;
}
for (int k = 0; k < n; k++)
if (!(bin[k]&i)) {
int S = (i|sta[k]|bin[k]), t = cnt[sta[k]]-cnt[sta[k]&i];
if (mx[S][j+t] < mx[i][j]+1) mx[S][j+t] = mx[i][j]+1, f[S][j+t] = f[i][j];
else if (mx[S][j+t] == mx[i][j]+1) (f[S][j+t] += f[i][j]) %= yzh;
}
}
int ans = f[bin[n]-1][0];
for (int i = 1; i <= n; i++) ans = 1ll*ans*inv[i]%yzh;
printf("%d\n", (ans+yzh)%yzh);
}
int main() {work(); return 0; }

[PKUWC 2018]随机算法的更多相关文章

  1. [PKUWC 2018]随机游走

    Description 题库链接 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次询问给定一个集合 \(S\) ...

  2. LOJ #2540. 「PKUWC 2018」随机算法(概率dp)

    题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...

  3. LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)

    写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...

  4. [PKUWC2018]随机算法

    题意:https://loj.ac/problem/2540 给定一个图(n<=20),定义一个求最大独立集的随机化算法 产生一个排列,依次加入,能加入就加入 求得到最大独立集的概率 loj25 ...

  5. PKUWC 2018游记

    PKUWC 2018游记 标签: Day\([-inf,0)\) 停课之后一直各种浪的飞起,考试rank20+,不搞颓但是学习很没有状态.还经常带着耳机被谢总抓了好几次,然后被拉过去谈话了好几次... ...

  6. A Dream (PKUWC 2018)

    A Dream (PKUWC 2018) 这是一个梦. 从没有几分节日气氛的圣诞,做到了大雪纷飞的数九寒天. 忘了罢! 不记得时间,不记得地点.随着记忆的褪去,一切也只会不复存在. Day-34? D ...

  7. $PkuWc\ 2018$ 酱油记

    PkuWc 2018 酱油记 1. Day -INF 又停了一个月课...... 感觉这个月的收获还是蛮大的,刚来的时候还只会线段树,到现在LCT都学了... 这个月不停在考试,自己考试技巧也提升了不 ...

  8. 【洛谷5492】[PKUWC2018] 随机算法(状压DP)

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

  9. 微信红包中使用的技术:AA收款+随机算法

    除夕夜你领到红包了吗?有的说“我领了好几K!”“我领了几W!” 土豪何其多,苦逼也不少!有的说“我出来工作了,没压岁钱了,还要发红包”.那您有去抢微信红包吗?微信群中抢“新年红包”春节爆红.618微信 ...

随机推荐

  1. Git Commit 标准化

    1 前言Git Commit Message 应该清晰明了,要用精简的语言说明本次提交的目的,其主要作用是为了后续的搜索.版本的回滚.合并冲突的追溯等操作. 我们在开发时一直以来对 Git Commi ...

  2. 曲演杂坛--HASH的一点理解

    HASH,百度百科上做如下定义: Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列 ...

  3. DBCC--SHOWCONTIG

    DBCC SHOWCONTIG是显示指定的表的数据和索引的碎片信息. Usage: dbcc SHOWCONTIG [ ( { 'table_name' | table_id | 'view_name ...

  4. leetcode 两数之和 II - 输入有序数组

    给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...

  5. C# GDI绘制波形图

    直接上效果图如下 public partial class WaveChartUserCtrl : UserControl { Color axisColor = Color.FromArgb(69, ...

  6. AOP面向切面的基石——动态代理(一)

    其实动态代理在Java里不是什么新技术了,早在java 1.2之后便通过 java.lang.reflect.InvocationHandler 加入了动态代理机制. 下面例子中,LancerEvol ...

  7. day85 ModuleForm Form组件

    1 forms组件与modelform组件 forms组件: https://www.cnblogs.com/yuanchenqi/articles/9036474.htmlmodelForm组件:h ...

  8. Day 27 类的进阶-反射

    11. __new__ 和 __metaclass__ 阅读以下代码: 1 2 3 4 5 6 class Foo(object): def __init__(self): pass obj = Fo ...

  9. brew - 安装gradle

    我安装完brew之后,马上开始安装gradle,但是shell总是卡在执行"brew update"这里,今天终于解决了,出现这样问题的原因是初次安装brew,它使用的源是国外的, ...

  10. leetcode 123. 买卖股票的最佳时机 III JAVA

    题目: 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意: 你不能同时参与多笔交易(你必须在再次购买前出 ...