题目描述

有 $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. 编程检查d:\test.txt文件是否存在,若在则显示该文件的名称和内容。

    下面放两种方法 老师写的: import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcept ...

  2. SystemView SEGGER FreeRTOS 移植和使用

    /* 官方帮助英文翻译文档参考:https://blog.csdn.net/bjr2016/article/category/7275877. */ /* 移植文档参考:https://blog.cs ...

  3. Linux常用系统信息查看命令

    [转]http://yulans.cn/linux/linux%E5%B8%B8%E7%94%A8%E7%B3%BB%E7%BB%9F%E4%BF%A1%E6%81%AF%E6%9F%A5%E7%9C ...

  4. 基于LBS平台的iOS开发

    LBS,即Location Based Services,基于位置服务,用于定位.导航等功能,比如地图应用.订外卖等的app就需要这个功能. 在这里我使用的是高德LBS开放平台,地址:http://l ...

  5. 数据结构与算法 基于c语言篇

    学习数据结构与算法走向深蓝之路 第一章:数据结构与算法概念型 数据结构:数据之间的相互关系,即是数据的组织形式. 基本组成:{ 数据:信息的载体 数据元素:数据基本单位: } 其结构形式有四种: 1, ...

  6. # 20155218 徐志瀚 EXP7 网络欺诈

    20155218 徐志瀚 EXP7 网络欺诈 1. URL攻击 1.在终端中输入命令netstat -tupln |grep 80,查看80端口是否被占用 发现没有被占用: 2.输入指令service ...

  7. 内存和CPU资源控制

    数据库系统的资源是指内存和CPU(处理器)资源,拥有资源的多寡,决定了数据查询的性能.当一个SQL Server实例上,拥有多个独立的工作负载(workload)时,使用资源管理器(Resource ...

  8. 起步 - vue-router路由与页面间导航

    vue-router 我们知道路由定义了一系列访问的地址规则,路由引擎根据这些规则匹配找到对应的处理页面,然后将请求转发给页进行处理.可以说所有的后端开发都是这样做的,而前端路由是不存在"请 ...

  9. spring boot 2.0 源码分析(五)

    在上一篇文章中我们详细分析了spring boot是如何准备上下文环境的,今天我们来看一下run函数剩余的内容.还是先把run函数贴出来: /** * Run the Spring applicati ...

  10. unity上传app store遇到的一些问题

    记录ios发布时遇到的一些问题 注:如果你是用mac开发,那就在Unity里直接BuildAndRun就直接可以导到XCode里,如果是win,那就先打包成ios包,在传导Xcode里打开,不过可能会 ...