题目描述

有 $n$ 个箱子,每个箱子里有且仅有一把钥匙,每个箱子有且仅有一把钥匙可以将其打开。现在随机打开 $m$ 个箱子,求能够将所有箱子打开的概率。


题解

组合数学+概率dp

题目约定了每个点的入度和出度均为1,因此最终的图一定是若干个环。每个环都至少选择一个点即可满足要求。

预处理出每个环的点数 $c[i]$ 以及其后缀和 $sum[i]$ 。

设 $f[i][j]$ 表示前 $i$ 个环中选出 $j$ 个点,满足最终条件的概率。初始化 $f[0][0]=1$ 。

枚举 $i$ 和前 $i-1$ 个环的点数 $j$ 、第 $i$ 个环的点数 $k$ ,那么:$i\sim n$ 的总方案数为 $C_{sum[i]}^{m-j}$ ,满足条件的方案数为 $c[i]$ 中选出 $k$ 个的方案数乘以剩下部分选出 $m-j-k$ 个的方案数 $C_{c[i]}^k·C_{sum[i]-c[i]}^{m-j-k}$ 。

整理一下即可得到dp方程 $f[i][j+k]\leftarrow f[i-1][j]·\frac{C_{c[i]}^k·C_{sum[i]-c[i]}^{m-j-k}}{C_{sum[i]}^{m-j}}$ 。

最后的答案就是 $f[n][m]$ 。

其中组合数直接使用double存据说能过,然而我比较怂,因此存的是阶乘的 $\ln$ ,求的时候再 $\text{exp}$ 回去。

时间复杂度 $O(Tn^2)$

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 310
using namespace std;
int a[N] , c[N] , vis[N] , sum[N];
double fac[N] , f[N][N];
int main()
{
int T;
scanf("%d" , &T);
while(T -- )
{
memset(vis , 0 , sizeof(vis));
memset(f , 0 , sizeof(f));
f[0][0] = 1;
int n , m = 0 , p , i , j , k;
scanf("%d%d" , &n , &p);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , fac[i] = fac[i - 1] + log(i);
for(i = 1 ; i <= n ; i ++ )
{
if(!vis[i])
{
c[++m] = 0;
for(j = i ; !vis[j] ; j = a[j])
vis[j] = 1 , c[m] ++ ;
}
}
sum[m + 1] = 0;
for(i = m ; i ; i -- ) sum[i] = sum[i + 1] + c[i];
for(i = 1 ; i <= m ; i ++ )
for(j = max(i - 1 , p - sum[i]) ; j < p && j <= n - sum[i] ; j ++ )
for(k = 1 ; k <= c[i] && j + k <= p ; k ++ )
f[i][j + k] += f[i - 1][j] * exp(fac[c[i]] + fac[sum[i] - c[i]] + fac[p - j] + fac[sum[i] - p + j] - fac[k] - fac[c[i] - k] - fac[p - j - k] - fac[sum[i] - c[i] - p + j + k] - fac[sum[i]]);
printf("%.9lf\n" , f[m][p]);
}
return 0;
}

【bzoj5004】开锁魔法II 组合数学+概率dp的更多相关文章

  1. HihoCoder 1075 开锁魔法III(概率DP+组合)

    描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...

  2. BZOJ 5004: 开锁魔法II 期望 + 组合

    Description 题面:www.lydsy.com/JudgeOnline/upload/task.pdf Input Output 一般概率题有两种套路: 满足条件的方案/总方案. 直接求概率 ...

  3. bzoj5003: 与链 5004: 开锁魔法II 5005:乒乓游戏

    www.lydsy.com/JudgeOnline/upload/task.pdf 第一题题意可以转为选一个长度k的序列,每一项二进制的1的位置被下一项包含,且总和为1,考虑每个二进制位的出现位置,可 ...

  4. BZOJ 5004: 开锁魔法II

    比较显然 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; i ...

  5. hihocoder1075【开锁魔法】

    hihocoder1075[开锁魔法] 题意是给你一个 \(1-n\) 的置换,求选 \(k\) 个可以遍历所有点的概率. 题目可以换个模型:有 \(n\) 个球,有 \(cnt\) 种不同的颜色,求 ...

  6. hrb——开锁魔法I——————【规律】

    解题思路:从1到n的倒数之和. #include<stdio.h> #include<string.h> #include<algorithm> using nam ...

  7. hihocoder 1075 : 开锁魔法III

    描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...

  8. #1075 : 开锁魔法III

    描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...

  9. Hiho #1075: 开锁魔法III

    Problem Statement 描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜 ...

随机推荐

  1. iis配置绑定二级域名的问题

    最近用destoon给客户做一个网站,涉及到站内企业网站的二级域名解析的问题,iis怎么配置绑定子目录绑定二级域名呢,查了好多资料,没有一个给出具体步骤的 基本是一些概念,不过看了这些东西基本理解了泛 ...

  2. float与double的范围和精度以及大小非零比较

    1. 范围  float和double的范围是由指数的位数来决定的.  float的指数位有8位,而double的指数位有11位,分布如下:  float:  1bit(符号位) 8bits(指数位) ...

  3. 板载CAN的树莓派扩展板Strato Pi CAN

    板载CAN的树莓派扩展板Strato Pi CAN   Sfera Labs推出了最新的树莓派扩展组件“灵云派”,其中包括CAN总线,电气隔离的RS-485,RTC和9-65V电源. 位于意大利米兰的 ...

  4. POJ 2388&&2299

    排序(水题)专题,毕竟如果只排序不进行任何操作都是极其简单的. 事实上,排序算法十分常用,在各类高级的算法中往往扮演着一个辅助的部分. 它看上去很普通,但实际的作用却很大.许多算法在失去排序后将会无法 ...

  5. 理解 NgModelController 中相关方法和属性

    1. 理解$formatters和$parsers方法 angular的双向绑定可以实现view和model中的值自动同步,但有时候我们不想让用户输入的(view值)和发送给后台的(model值)并不 ...

  6. md5加密,同样的代码得到不同的加密结果(已解决)

    场景: 开发环境(windows下)调用第三方接口验签通过,发测试环境(linux下)后死活验签通过不了 原因: md5是一项成熟的加密技术,问题应该在代码里,查了查感觉可能是字符编码的问题,导致加签 ...

  7. [BZOJ2687]交与并[决策单调性]

    题意 给定 \(n\) 个区间,我们定义区间集合 \(S(|S|>1)\) 的权值为 区间交 \(\times\) 区间并,找出权值最大的区间集合. \(n\le 10^6\) 分析 首先排除区 ...

  8. Java设计模式之适配器设计模式(项目升级案例)

    今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一 ...

  9. 使用pyspark模仿sqoop从oracle导数据到hive的主要功能(自动建表,分区导入,增量,解决数据换行符问题)

    最近公司开始做大数据项目,让我使用sqoop(1.6.4版本)导数据进行数据分析计算,然而当我们将所有的工作流都放到azkaban上时整个流程跑完需要花费13分钟,而其中导数据(增量)就占了4分钟左右 ...

  10. 教你如何自学UI设计

    一.常用的UI相关工具软件 PS Adobe Illustrator(AI) C4D AE Axure Sketch 墨刀 Principle Cutterman PxCook Zeplin 蓝湖 X ...