LOJ2540 PKUWC2018 随机算法 状压DP
两种$DP$:
①$f_{i,j}$表示前$i$次选择,最大独立集为$j$时达到最大独立集的方案总数,转移:$a.f_{i,j}+=f_{i+1,j+2^k}$(保证$k$加入后符合条件);$b.f_{i,j}+=f_{i+1,j} \times \text{现在可以放的不影响最大独立集的点的数量}$,这个现在可以放的不影响最大独立集的点的数量就是不可选择的点(即已经选择和与已经选择的点相邻的点)的数量$-i$
复杂度$O(2^nn^2)$而且似乎无法优化
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std; inline int read(){
int a = ;
bool f = ;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ '');
c = getchar();
}
return f ? -a : a;
} const int MOD = ;
bool can[][ << ] , edge[][] , choose[];
int dp[][ << ] , cnt1[ << ] , N , M , maxN , logg2[ << ]; inline int poww(long long a , int b){
int times = ;
while(b){
if(b & )
times = times * a % MOD;
a = a * a % MOD;
b >>= ;
}
return times;
} void dfs(int now , int size){
if(N - now + size <= maxN)
return;
if(now == N){
maxN = size;
return;
}
dfs(now + , size);
for(int i = ; i < now ; ++i)
if(choose[i] && edge[i][now])
return;
choose[now] = ;
dfs(now + , size + );
choose[now] = ;
} int main(){
#ifndef ONLINE_JUDGE
freopen("2540.in" , "r" , stdin);
//freopen("2540.out" , "w" , stdout);
#endif
N = read();
logg2[] = -;
for(int i = ; i < ( << N) ; ++i){
cnt1[i] = cnt1[i - (i & -i)] + ;
logg2[i] = logg2[i >> ] + ;
}
for(M = read() ; M ; --M){
int a = read() - , b = read() - ;
edge[a][b] = edge[b][a] = ;
}
dfs( , );
for(int i = ; i < N ; ++i){
can[i][] = ;
for(int j = ; j < ( << N) ; ++j)
if(!(j & ( << i)))
if(can[i][j - (j & -j)]){
int minN = logg2[j & -j];
if(!edge[i][minN])
can[i][j] = ;
}
}
for(int i = ; i < ( << N) ; ++i)
if(cnt1[i] == maxN)
dp[N][i] = ;
for(int i = N - ; i ; --i)
for(int j = ; j < ( << N) ; ++j)
if(cnt1[j] <= i && cnt1[j] <= maxN){
int cnt = ;
for(int p = (( << N) - ) ^ j ; p ; p ^= p & -p){
int k = logg2[p & -p];
if(can[k][j])
dp[i][j] = (dp[i][j] + dp[i + ][j | ( << k)]) % MOD;
else
++cnt;
}
dp[i][j] = (dp[i][j] + 1ll * dp[i + ][j] * (cnt + cnt1[j] - i)) % MOD;
}
long long sum = , ans = ;
for(int i = ; i < N ; ++i)
sum = (sum + dp[][ << i]) % MOD;
for(int i = ; i <= N ; ++i)
ans = ans * i % MOD;
cout << sum * poww(ans , MOD - ) % MOD;
return ;
}
②$f_{j}$表示当前已经无法选择(即已经选择和与已经选择的点相邻的点)的集合为$j$时、独立集取到最大的方案数,设$w_i$表示与$i$相邻(包括$i$)的点集,则有转移:$f_{S \cup w_i}+=f_{S} \times P_{N - |S| - 1}^{|S| - |S \cap w_i| - 1}$,记得要满足最大独立集大小要是最大的。
复杂度$O(2^nn)$
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std; inline int read(){
int a = ;
bool f = ;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ '');
c = getchar();
}
return f ? -a : a;
} const int MOD = ;
long long dp[ << ] , maxN[ << ] , cnt1[ << ] , need[] , jc[] = {} , ny[] = {} , N , M; inline int poww(long long a , int b){
int times = ;
while(b){
if(b & )
times = times * a % MOD;
a = a * a % MOD;
b >>= ;
}
return times;
} int main(){
#ifndef ONLINE_JUDGE
freopen("2540.in" , "r" , stdin);
//freopen("2540.out" , "w" , stdout);
#endif
N = read();
for(int i = ; i < << N ; ++i)
cnt1[i] = cnt1[i - (i & -i)] + ;
jc[] = ny[] = ;
for(int i = ; i <= N ; ++i)
jc[i] = jc[i - ] * i % MOD;
ny[N] = poww(jc[N] , MOD - );
for(int i = N - ; i > ; --i)
ny[i] = ny[i + ] * (i + ) % MOD;
for(int i = ; i < N ; ++i)
need[i] = << i;
for(M = read() ; M ; --M){
int a = read() - , b = read() - ;
need[a] |= << b;
need[b] |= << a;
}
dp[] = ;
for(int i = ; i + < ( << N) ; ++i)
for(int j = ; j < N ; ++j)
if(!(i & ( << j)) && maxN[i] + >= maxN[i | need[j]]){
if(maxN[i] + > maxN[i | need[j]]){
maxN[i | need[j]] = maxN[i] + ;
dp[i | need[j]] = ;
}
dp[i | need[j]] = (dp[i | need[j]] + dp[i] * jc[N - cnt1[i] - ] % MOD * ny[N - cnt1[i] - - (cnt1[need[j]] - cnt1[i & need[j]] - )]) % MOD;
}
cout << dp[( << N) - ] * ny[N] % MOD;
return ;
}
LOJ2540 PKUWC2018 随机算法 状压DP的更多相关文章
- [LOJ2540] [PKUWC2018] 随机算法
题目链接 LOJ:https://loj.ac/problem/2540 Solution 写的时候脑子不太清醒码了好长然后时间\(LOJ\)垫底... 反正随便状压\(dp\)一下就好了,设\(f[ ...
- LOJ2540 [PKUWC2018] 随机算法 【状压DP】
题目分析: 听说这题考场上能被$ O(4^n) $的暴力水过,难不成出题人是毕姥爷? 首先思考一个显而易见的$ O(n^2*2^n) $的暴力DP.一般的DP都是考虑最近的加入了哪个点,然后删除后递归 ...
- 洛谷 P4547 & bzoj 5006 随机二分图 —— 状压DP+期望
题目:https://www.luogu.org/problemnew/show/P4547 https://www.lydsy.com/JudgeOnline/problem.php?id=5006 ...
- loj2540 「PKUWC2018」随机算法 【状压dp】
题目链接 loj2540 题解 有一个朴素三进制状压\(dp\),考虑当前点三种状态:没考虑过,被选入集合,被排除 就有了\(O(n3^{n})\)的转移 但这样不优,我们考虑优化状态 设\(f[i] ...
- 【洛谷5492】[PKUWC2018] 随机算法(状压DP)
点此看题面 大致题意: 用随机算法求一张图的最大独立集:每次随机一个排列,从前到后枚举排列中的点,如果当前点加入点集中依然是独立集,就将当前点加入点集中,最终得到的点集就是最大独立集.求这个随机算法的 ...
- 「算法笔记」状压 DP
一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...
- 算法笔记-状压dp
状压dp 就是把状态压缩的dp 这样还是一种暴力但相对于纯暴力还是优雅的多. 实际上dp就是经过优化的暴力罢了 首先要了解位运算 给个链接吧 [https://blog.csdn.net/u01337 ...
- Luogu4547 THUWC2017 随机二分图 概率、状压DP
传送门 考虑如果只有$0$组边要怎么做.因为$N \leq 15$,考虑状压$DP$.设$f_i$表示当前的匹配情况为$i$时的概率($i$中$2^0$到$2^{N-1}$表示左半边的匹配情况,$2^ ...
- 算法复习——状压dp
状压dp的核心在于,当我们不能通过表现单一的对象的状态来达到dp的最优子结构和无后效性原则时,我们可能保存多个元素的有关信息··这时候利用2进制的01来表示每个元素相关状态并将其压缩成2进制数就可以达 ...
随机推荐
- 从零开始学习html(七)CSS样式基本知识
一.内联式css样式,直接写在现有的HTML标签中 <!DOCTYPE HTML> <html> <head> <meta http-equiv=" ...
- Windows下更新 npm 和 nodejs
一.更新npm // 将npm更新到最新版本 npm install npm@latest -g 二.更新nodejs 1. 首先通过 where node 命令找到nodejs的安装路径 2. 然后 ...
- SAP MM PIR里的Lower Limit & Upper Limit
SAP MM PIR里的Lower Limit & Upper Limit 在PIR的价格的detail数据里,有2个字段:Lower Limit和Upper Limit.在今天之前,笔者从未 ...
- Linux 学习笔记之超详细基础linux命令 Part 7
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 6----------------- ...
- 《ASP.NET MVC企业实战》(一) MVC开发前奏
一.工具和方法 学到了一些没用过的工具和方法: a)删除多余的using指令并排序:一个类头部的using一般会有很多用不到的,在完成类的编写后,可以右键选择”组织using”来删除没用的using并 ...
- Android Stuido代码混淆
一.Android Studio 代码混淆基本配置首先我们要在build.gradle里设置 miifyEnabled 里改为true,表示可以混淆 proguardFiles getDefaultP ...
- 基于Jmeter和Testlink的自动化测试框架研究与实施
关于测试框架搭建的详细过程,会在另一篇文章中详细介绍:http://www.cnblogs.com/leeboke/p/6145977.html 摘 要 目前基于Jmeter的接口自动化测试框架,大多 ...
- 安装Django(1)
安装Django 注意:因为这是web项目将来要部署在Linux上,所以使用centos/ubuntu:因为Python3是将来的趋势,所以使用Python3做为开发语言.本人使用的开发模式操作系统: ...
- CSS图片水平垂直居中
Html: <div id="></img></div> </div> CSS: #MainContent { display:table-c ...
- elasticsearch版本控制及mapping映射属性介绍
学习elasticsearch不仅只会操作,基本的运行原理我们还是需要进行了解,以下内容我讲对elasticsearch中的基本知识原理进行梳理,希望对大家有所帮助! 一.ES版本控制 1.Elast ...