pkusc 快到了……做点题涨涨 rp。

记 \(f(S,i)\) 表示 \(S\) 这个集合是决计不能选的(要么属于独立集,要么和独立集相连),或称已经考虑了的,\(i\) 表示此集合对应的最大独立集大小。那么枚举一下哪些点 \(j\) 不在 \(S\) 里,记 \(w_i\) 表示 \(i\) 和与之相邻的点集,则 \(f(S \cup w_j,i+1) \leftarrow f(S \cup w_j,i+1) + f(S,i) \times A_{n-|S|-1}^{|w_j-(w_j \cap S)|-1}\)。

然而对于一个集合 \(S\),它的最大独立集大小是确定的,那么就来一个数组 \(mx_S\) 来记录其最大独立集大小。当最大独立集大小更新之时,\(dp_S\) 就清零然后再计数就行了。复杂度从 \(O(\)跑得过\()\) 变成了 \(O(\)更跑得过\()\),也就是\(O(n^22^n)\) 变成了 \(O(n2^n)\)……。

改进前:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, m, w[25], uu, vv, jie[25], inv[25], dp[25][1050005], cnt[1050005];
const int mod=998244353;
int A(int x, int y){
// if(x<y) return 0;
return (ll)jie[x]*inv[x-y]%mod;
}
int main(){
cin>>n>>m;
for(int i=1; i<=m; i++){
scanf("%d %d", &uu, &vv);
uu--; vv--;
w[uu] |= 1<<vv;
w[vv] |= 1<<uu;
}
jie[0] = jie[1] = inv[0] = inv[1] = 1;
for(int i=2; i<=n; i++){
jie[i] = (ll)jie[i-1] * i % mod;
inv[i] = (ll)(mod - mod / i) * inv[mod%i] % mod;
}
for(int i=0; i<n; i++)
w[i] |= 1<<i;
for(int i=2; i<=n; i++)
inv[i] = (ll)inv[i-1] * inv[i] % mod;
for(int i=0; i<(1<<n); i++)
for(int j=0; j<n; j++)
if(i&(1<<j))
cnt[i]++;
dp[0][0] = 1;
for(int i=0; i<n; i++)
for(int s=0; s<(1<<n); s++)
if(dp[i][s])
for(int j=0; j<n; j++)
if(!(s&(1<<j)))
dp[i+1][s|w[j]] = (dp[i+1][s|w[j]] + (ll)dp[i][s] * A(n-cnt[s]-1, cnt[w[j]-(w[j]&s)]-1)%mod) % mod;
for(int i=n; i; i--)
if(dp[i][(1<<n)-1]){
cout<<(ll)dp[i][(1<<n)-1]*inv[n]%mod<<endl;
return 0;
}
return 0;
}

改进后:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, m, w[25], uu, vv, jie[25], inv[25], dp[1050005], cnt[1050005];
int mx[1050005];
const int mod=998244353;
int A(int x, int y){
// if(x<y) return 0;
return (ll)jie[x]*inv[x-y]%mod;
}
int main(){
cin>>n>>m;
for(int i=1; i<=m; i++){
scanf("%d %d", &uu, &vv);
uu--; vv--;
w[uu] |= 1<<vv;
w[vv] |= 1<<uu;
}
jie[0] = jie[1] = inv[0] = inv[1] = 1;
for(int i=2; i<=n; i++){
jie[i] = (ll)jie[i-1] * i % mod;
inv[i] = (ll)(mod - mod / i) * inv[mod%i] % mod;
}
for(int i=0; i<n; i++)
w[i] |= 1<<i;
for(int i=2; i<=n; i++)
inv[i] = (ll)inv[i-1] * inv[i] % mod;
for(int i=0; i<(1<<n); i++)
for(int j=0; j<n; j++)
if(i&(1<<j))
cnt[i]++;
dp[0] = 1;
for(int s=0; s<(1<<n); s++)
if(dp[s])
for(int i=0; i<n; i++)
if(!(s&(1<<i))){
int t=s|w[i];
if(mx[t]<mx[s]+1) mx[t] = mx[s] + 1, dp[t] = 0;
if(mx[t]==mx[s]+1)
dp[t] = (dp[t] + (ll)dp[s] * A(n-cnt[s]-1, cnt[w[i]-(w[i]&s)]-1)%mod) % mod;
}
cout<<(ll)dp[(1<<n)-1]*inv[n]%mod<<endl;
return 0;
}

loj2540 「PKUWC 2018」随机算法的更多相关文章

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

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

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

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

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

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

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

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

  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. loj2538 「PKUWC 2018」Slay the Spire

    pkusc 快到了--做点题涨涨 rp. ref我好菜啊QAQ. 可以发现期望只是一个幌子.我们的目的是:对于所有随机的选择方法(一共 \(\binom{2n}{m}\)种),这些选择方法都最优地打出 ...

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

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

  9. 「PKUWC 2018」Minimax

    传送门:Here 一道线段树合并好题 如果要维护点$ x$的信息,相当于合并$ x$的两棵子树 对于这题显然有:任何叶子节点的权值都可能出现在其祖先上 因而我们只需要在线段树合并的时候维护概率即可 我 ...

随机推荐

  1. 【tp5.1】七牛云上传图片

    composer安装: composer require qiniu/php-sdk 配置使用: 在tp5.1的配置文件app.php中配置七牛云的参数 'qiniu' => [ 'access ...

  2. 如何导入XML数据 (python3.6.6区别于python2 环境)

    1.在python2中 代码如下图: 放在python3 环境下执行,将出现如下错误: 原因: python2中形如myTree.keys()[0]这样的写法是没有问题的,因为myTree.keys( ...

  3. ctf题目writeup(1)

    2019/1/28 题目来源:爱春秋 https://www.ichunqiu.com/battalion?t=1 1. 该文件是一个音频文件: 首先打开听了一下,有短促的长的....刚开始以为是摩斯 ...

  4. C# 设置程序最小化到任务栏右下角,鼠标左键单击还原,右键提示关闭程序

    首先设置程序最小化到任务栏右下角 先给窗口添加一个notifyIcon控件 为notifyIcon控件设置ICO图标(不设置图标将无法在任务栏显示) 给notifyIcon控件添加点击事件 然后是最小 ...

  5. (数据科学学习手札08)系统聚类法的Python源码实现(与Python,R自带方法进行比较)

    聚类分析是数据挖掘方法中应用非常广泛的一项,而聚类分析根据其大体方法的不同又分为系统聚类和快速聚类,其中系统聚类的优点是可以很直观的得到聚类数不同时具体类中包括了哪些样本,而Python和R中都有直接 ...

  6. R语言绘图:ggplot2绘制ROC

    使用ggplot2包绘制ROC曲线 rocplot<- function(pred, truth, ...){ predob<- prediction(pred, truth) #打印AU ...

  7. 10-mongodb启动错误

    1.error信息 python@ubuntu:~$ mongod --22T17:: I CONTROL [initandlisten] MongoDB starting : pid= port= ...

  8. express操作数据库

    Express 首页 入门 使用指南 API 中文手册 进阶话题 有用的资源 集成数据库 为 Express 应用添加连接数据库的能力,只需要加载相应数据库的 Node.js 驱动即可.这里将会简要介 ...

  9. OrCAD生成网表

    1. 先选中.dsn设计文件 2. 按照默认设置,点击OK即可生成网表

  10. 常用js方法合集

    var Default = { init: function () { }, addCookie: function (name,data) { var expdate = new Date(); / ...