题意

LOJ #2540. 「PKUWC 2018」随机算法

题解

朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 , 考虑了并且在独立集中 , 还没考虑 . 转移就很显然了 qwq

然后要优化嘛 , 把其中两个状态合起来 , 也就是分成考虑了和没考虑了的两种 .

其中考虑了的那种 , 只会存在两种状态 , 要么是在独立集内 , 要么就是与独立集联通 , 没有考虑的 绝对不和独立集联通 就行了 .

然后我们枚举一个集合 , 考虑强制把一个点选进来 . 如果要选它 , 那么它周围的一圈都不能去选 .

为了使这个 dp 不存在后效性 , 我们不能让之后的选的点连得点存在于独立集中 , 我们把他周围一圈的都放进来就行了 .

也就是说当前维护的集合 , 会被最外面没有存在于独立集中的一圈给包围住 .

然后连上来的时候会有很多种排列的方式 , 直接乘上一个排列数就行了 . (相当于预留位置)

最后算答案因为是概率 , 除以 \(\frac{1}{n!}\) 就行了 .

这些我都是问 DOFY 才懂的 , 还是太菜啦 ~

具体来说 方程是这样的 (\(\displaystyle f_{i,s}\) 当前选了 \(i\) 个点 , 考虑过的集合是 \(s\) , 与 \(k\) 相邻的所有点(包括它自己)的集合为 \(w_k\) ):

\[[k \notin s] ~ \displaystyle f_{i,s} \times A_{n-|s|-1}^{|w_k-w_k \cap s|} \to f_{i+1,s \cup w_k}
\]

时间复杂度是 \(O(n^2 2^n)\) 可以通过此题了 .

然后进行一波优化 , 对于一个确定的考虑过的集合 \(s\) 那么它选取最大独立集 , 是选取全局的最大独立集的必要条件 .

(这个应该显然吧 ... 因为最外圈你不要的话 , 如果里面不是最大独立集的话 , 外面取得最大也达不到全局最大)

那么第一位考虑选点的就可以不要了 , 时间复杂度就是 \(O(n2^n)\) .

这样写了一下 莫名奇妙就是 LOJ 最快的了 ?

代码

#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std; inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
return x * fh;
} void File() {
#ifdef zjp_shadow
freopen ("2540.in", "r", stdin);
freopen ("2540.out", "w", stdout);
#endif
} const int N = 20;
int n, m, Con[N]; typedef long long ll;
const int Mod = 998244353; ll fpm(ll x, int power) {
ll inv = 1;
for (; power; power >>= 1, (x *= x) %= Mod)
if (power & 1) (inv *= x) %= Mod;
return inv;
} ll fac[N + 5], ifac[N + 5];
void Init(int maxn) {
fac[0] = ifac[0] = 1;
For (i, 1, maxn) fac[i] = fac[i - 1] * i % Mod;
ifac[maxn] = fpm(fac[maxn], Mod - 2);
Fordown (i, maxn - 1, 1) ifac[i] = ifac[i + 1] * (i + 1) % Mod;
} int dp[1 << N], bit[1 << N], MaxSize[1 << N];; inline int A(int n, int m) { if (m > n || n < 0 || m < 0) return 0; return fac[n] * ifac[n - m] % Mod; } int main () {
File(); n = read(); m = read(); Init(n);
For (i, 1, m) {
int u = read() - 1, v = read() - 1;
Con[u] |= (1 << v);
Con[v] |= (1 << u);
} For (i, 0, n - 1) Con[i] |= (1 << i); dp[0] = 1;
int maxsta = (1 << n) - 1;
For (i, 0, maxsta) bit[i] = bit[i >> 1] + (i & 1); For (i, 0, maxsta) if (dp[i]) {
For (j, 0, n - 1) if (!((1 << j) & i)) {
register int Next = i | Con[j];
if (chkmax(MaxSize[Next], MaxSize[i] + 1)) dp[Next] = 0;
if (MaxSize[Next] == MaxSize[i] + 1) (dp[Next] += 1ll * dp[i] * A(n - bit[i] - 1, bit[Con[j] ^ (Con[j] & i)] - 1) % Mod) %= Mod;
}
} printf ("%lld\n", 1ll * dp[maxsta] * ifac[n] % Mod);
return 0;
}

LOJ #2540. 「PKUWC 2018」随机算法(概率dp)的更多相关文章

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

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

  2. loj2540 「PKUWC 2018」随机算法

    pkusc 快到了--做点题涨涨 rp. 记 \(f(S,i)\) 表示 \(S\) 这个集合是决计不能选的(要么属于独立集,要么和独立集相连),或称已经考虑了的,\(i\) 表示此集合对应的最大独立 ...

  3. 「PKUWC 2018」随机算法 (第二版,正解做法)

    上一版貌似是打了 O(3 ^ N) 暴力和 一条链的情况,得了60分.... 第一次做的时候光想练一练暴力...就没去想正解,谁知道正解比暴力好写不知道多少,mmp 设 f(S) 为 选集合S中的点可 ...

  4. 「PKUWC 2018」随机算法 (60分部分分做法)

    明天就是CTSC的DAY 2了qwq,晚上敲敲暴力攒攒RP,果断随便看了个题就是打暴力hhhhh 前50% O(3^N) 暴力没什么好说的,我们设F[S][s]为已经选了S集合中的点,并且这个集合中的 ...

  5. LOJ #2541. 「PKUWC 2018」猎人杀(容斥 , 期望dp , NTT优化)

    题意 LOJ #2541. 「PKUWC 2018」猎人杀 题解 一道及其巧妙的题 , 参考了一下这位大佬的博客 ... 令 \(\displaystyle A = \sum_{i=1}^{n} w_ ...

  6. LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)

    Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...

  7. LOJ #2802. 「CCC 2018」平衡树(整除分块 + dp)

    题面 LOJ #2802. 「CCC 2018」平衡树 题面有点难看...请认真阅读理解题意. 转化后就是,给你一个数 \(N\) ,每次选择一个 \(k \in [2, N]\) 将 \(N\) 变 ...

  8. LOJ #2537. 「PKUWC 2018」Minimax (线段树合并 优化dp)

    题意 小 \(C\) 有一棵 \(n\) 个结点的有根树,根是 \(1\) 号结点,且每个结点最多有两个子结点. 定义结点 \(x\) 的权值为: 1.若 \(x\) 没有子结点,那么它的权值会在输入 ...

  9. loj 2778「BalticOI 2018」基因工程

    loj luogu 这题和NOI那道向量内积一个套路 首先考虑求两行的不同元素个数,可以转化成一个行向量\(a\)和列向量\(b\)相乘得到一个值.如果只有\(A,C\)两种字符,那么令对应权值\(A ...

随机推荐

  1. NOIP2002-2017普及组题解

    虽然普及组一般都是暴力省一,但是有一些题目还是挺难的qwq个人觉得能进TG的题目会在前面打上'*' NOIP2002(clear) #include<bits/stdc++.h> usin ...

  2. Luogu4622 COCI2012-2013#6 JEDAN 组合、DP

    传送门 题意:给出一个$N$个数的序列$a_i$,其中$a_i=-1$表示第$i$个位置数字未知,问有多少种用非负整数代替$a_i$中$-1$的方法使得从全$0$序列经过以下操作若干次得到序列$a_i ...

  3. 把DataTable转换为List<T>

    前一篇有学习过<把List<T>转换为DataTable>http://www.cnblogs.com/insus/p/8043173.html 那此篇,将是学习反向,把Dat ...

  4. PowerDesign 16.0 生成的SQL Server2000 数据库脚本时MS_Description不存在的问题解决

    根据网上查询到的资料,找到了解决方法,原文出自:http://www.cnblogs.com/24tt/p/5047257.html PowerDesign 16.0 生成的Script语句,Sql2 ...

  5. linux中fork, source和exec的区别

    转:linux中fork, source和exec的区别 shell的命令可以分为内部命令和外部命令. 内部命令是由特殊的文件格式.def实现的,如cd,ls等.而外部命令是通过系统调用或独立程序实现 ...

  6. JDK8漫谈——增强接口

    解决什么问题 向下兼容.添加方法,所有的实现类必须实现此方法,否则会编译报错.这意味着每一次的接口升级都会伤筋动骨.但是这是一把双刃剑一定要把握好场景,不要滥用. 类爆炸.使用时,需要辅助类.即要记忆 ...

  7. 因写太多 BUG!程序员遭公司颁奖羞辱,做的一个比一个绝​

    刚入职的程序员新人,办公桌上,基本上也就一电脑.一键盘.一鼠标,再配个被杯子.然而混迹职场多年的猿老们,办公桌上都有一些彰显身份地位的“好东西”. 这张图两点颇多,最显眼的,是办公桌上那个黄黄的东西, ...

  8. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(六)一定要RESTful吗?

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 写在前面的话 这个问题看起来就显得有些萌,或者说类似的问题都有些不靠 ...

  9. NTP服务部署和测试

    1. 概述2. 部署3. 配置4. 客户端配置4.1 客户端安装ntpdate4.2 同步设置 1. 概述 本篇博客主要记录如何部署一台NTP服务器,用于内网时间同步. 时间服务器对于集群内部节点之间 ...

  10. 小白必须懂的MongoDB的十大总结

    小白必须懂的MongoDB的总结 一.MongoDB的认识 1.什么是MongoDB? MongoDB 是一个介于关系数据库和非关系数据库之间的开源产品,是最接近于关系型数据库的 NoSQL 数据库. ...