LOJ #2540. 「PKUWC 2018」随机算法(概率dp)
题意
题解
朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 , 考虑了并且在独立集中 , 还没考虑 . 转移就很显然了 qwq
然后要优化嘛 , 把其中两个状态合起来 , 也就是分成考虑了和没考虑了的两种 .
其中考虑了的那种 , 只会存在两种状态 , 要么是在独立集内 , 要么就是与独立集联通 , 没有考虑的 绝对不和独立集联通 就行了 .
然后我们枚举一个集合 , 考虑强制把一个点选进来 . 如果要选它 , 那么它周围的一圈都不能去选 .
为了使这个 dp 不存在后效性 , 我们不能让之后的选的点连得点存在于独立集中 , 我们把他周围一圈的都放进来就行了 .
也就是说当前维护的集合 , 会被最外面没有存在于独立集中的一圈给包围住 .
然后连上来的时候会有很多种排列的方式 , 直接乘上一个排列数就行了 . (相当于预留位置)
最后算答案因为是概率 , 除以 \(\frac{1}{n!}\) 就行了 .
这些我都是问 DOFY 才懂的 , 还是太菜啦 ~
具体来说 方程是这样的 (\(\displaystyle f_{i,s}\) 当前选了 \(i\) 个点 , 考虑过的集合是 \(s\) , 与 \(k\) 相邻的所有点(包括它自己)的集合为 \(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)的更多相关文章
- LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)
写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...
- loj2540 「PKUWC 2018」随机算法
pkusc 快到了--做点题涨涨 rp. 记 \(f(S,i)\) 表示 \(S\) 这个集合是决计不能选的(要么属于独立集,要么和独立集相连),或称已经考虑了的,\(i\) 表示此集合对应的最大独立 ...
- 「PKUWC 2018」随机算法 (第二版,正解做法)
上一版貌似是打了 O(3 ^ N) 暴力和 一条链的情况,得了60分.... 第一次做的时候光想练一练暴力...就没去想正解,谁知道正解比暴力好写不知道多少,mmp 设 f(S) 为 选集合S中的点可 ...
- 「PKUWC 2018」随机算法 (60分部分分做法)
明天就是CTSC的DAY 2了qwq,晚上敲敲暴力攒攒RP,果断随便看了个题就是打暴力hhhhh 前50% O(3^N) 暴力没什么好说的,我们设F[S][s]为已经选了S集合中的点,并且这个集合中的 ...
- LOJ #2541. 「PKUWC 2018」猎人杀(容斥 , 期望dp , NTT优化)
题意 LOJ #2541. 「PKUWC 2018」猎人杀 题解 一道及其巧妙的题 , 参考了一下这位大佬的博客 ... 令 \(\displaystyle A = \sum_{i=1}^{n} w_ ...
- LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)
Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...
- LOJ #2802. 「CCC 2018」平衡树(整除分块 + dp)
题面 LOJ #2802. 「CCC 2018」平衡树 题面有点难看...请认真阅读理解题意. 转化后就是,给你一个数 \(N\) ,每次选择一个 \(k \in [2, N]\) 将 \(N\) 变 ...
- LOJ #2537. 「PKUWC 2018」Minimax (线段树合并 优化dp)
题意 小 \(C\) 有一棵 \(n\) 个结点的有根树,根是 \(1\) 号结点,且每个结点最多有两个子结点. 定义结点 \(x\) 的权值为: 1.若 \(x\) 没有子结点,那么它的权值会在输入 ...
- loj 2778「BalticOI 2018」基因工程
loj luogu 这题和NOI那道向量内积一个套路 首先考虑求两行的不同元素个数,可以转化成一个行向量\(a\)和列向量\(b\)相乘得到一个值.如果只有\(A,C\)两种字符,那么令对应权值\(A ...
随机推荐
- CF875F Royal Questions 基环树、Kruskal
题目传送门:http://codeforces.com/problemset/problem/875/F 题意:有$N$个王子和$M$个公主,每个公主或王子都只能选择至多一个王子或公主作为自己的结婚对 ...
- 【转】单KEY业务,数据库水平切分架构实践
本文将以“用户中心”为例,介绍“单KEY”类业务,随着数据量的逐步增大,数据库性能显著降低,数据库水平切分相关的架构实践: 如何来实施水平切分 水平切分后常见的问题 典型问题的优化思路及实践 一.用户 ...
- Intellij IDEA的下载和使用(针对学生的免费使用计划)
一.下载和使用授权(针对学生) 1.下载 可以在Intellij IDEA官网上下载需要的版本.下载地址:https://www.jetbrains.com/idea/ 2.学生免费试用 首先,你得现 ...
- 浅谈移动端设备标识码:DeviceID、IMEI、IDFA、UDID和UUID
---恢复内容开始--- 转:https://www.jianshu.com/p/38f4d1a4763b [心路历程] 最近刚好在思考工作中统计数据所用的标识码产生的数据误差到底有多大,借此机会几番 ...
- [T-ARA][ORGR]
歌词来源:http://music.163.com/#/song?id=29343993 作曲 : 4번타자/에스킴 [作曲 : 4p/beon-Ta-c/ja-/e-seu-Kim] 作词 : 4번 ...
- kvm虚拟化管理平台WebVirtMgr部署-完整记录(0)
打算部署kvm虚拟机环境,下面是虚拟化部署前的一些准备工作: 操作系统环境安装1)修改内核模式为兼容内核启动[root@ops ~]# uname -aLinux openstack 2.6.32-4 ...
- Maven 项目生成或者update jdk变为1.5的问题
在使用Maven构建项目时,生成的maven项目jdk默认使用的是jdk1.5. 在手动修改了jdk之后,update project之后jdk又会变为1.5. 或者用eclipse的Maven插件生 ...
- Jmeter(非GUI模式)教程
前言 使用非 GUI 模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资源.优点如下:1.节约系统资源:无需启动界面,节约系统资源 2.便捷快速:仅需启动命令行,输入命令便可执行 ...
- 个人阅读作业LAST
其实从最刚开始到最后,我们团队的任务一直都比较紧,前期主要是因为我们是从零开始的自选题目,一开始大家都有许多不曾用过的技术需要学习,PM安排任务时也不好分配,不过大家也都坚持下来尽量按时完成任务,第一 ...
- 嵌入式linux教程
串口通信minicom $ sudo apt-get install minicom ///安装 # minicom –s //运行 //CTRL+A Z 弹出菜单 2.NFS网络文件配置 ...