开锁

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

  

Input

  

Output

  

Sample Input

  4
  5 1
  2 5 4 3 1
  5 2
  2 5 4 3 1
  5 3
  2 5 4 3 1
  5 4
  2 5 4 3 1

Sample Output

  0.000000000
  0.600000000
  0.900000000
  1.000000000

HINT

  

Main idea

  一个宝箱内有一个可以开启别的宝箱的钥匙,可以选择k个宝箱,询问能开启所有宝箱的概率。

Solution

  我们一看就知道这是一道概率DP的题目。

  我们发现,每个宝箱有一个对应的钥匙,那么显然若干个宝箱会构成一个环,只要开了一个环中的一个宝箱就可以开启这个环。

  那么我们要求的就是:在n个数中选k次,已知每个环的大小,选中环中的一个元素即视为选中了这个环,问每个环都被至少选了一次的概率。

  显然直接记概率不好计算,于是我们可以算出可行的方案数。

  我们先求出每个环的大小,然后令 f[i][j] 表示前 i 个环选了 j 个元素的方案数,那么显然可以枚举这一个环中选了几个,那么显然有:

  然后我们最后用 f[num][k] / 总方案数 C(n,k) 即可。注意要用double来存,否则数字不够大。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std; const int ONE=; int T,n,k;
int a[ONE],vis[ONE],cnt;
int ring[ONE],num;
int record;
double C[ONE][ONE];
double f[ONE][ONE]; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} void Solve()
{
n=get(); k=get(); for(int i=;i<=n;i++) a[i]=get(),vis[i]=;
num=;
for(int i=;i<=n;i++)
{
if(vis[i]) continue;
int x=i;
cnt=;
for(;;)
{
vis[x]=; x=a[x]; cnt++;
if(x==i) break;
}
ring[++num]=cnt;
} memset(f,,sizeof(f));
f[][]=; record=;
for(int i=;i<=num;i++)
{
record+=ring[i];
for(int j=;j<=record;j++)
{
for(int x=;x<=ring[i] && x<=j;x++)
{
f[i][j] += f[i-][j-x] * C[ring[i]][x];
}
}
} cout<<(double)f[num][k]/C[n][k]<<endl;
} int main()
{
C[][]=;
for(int i=;i<=;i++)
{
C[i][]=;
for(int j=;j<=;j++)
C[i][j]=C[i-][j-]+C[i-][j];
} T=get();
while(T--)
Solve(); }

【Foreign】开锁 [概率DP]的更多相关文章

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

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

  2. 【bzoj5004】开锁魔法II 组合数学+概率dp

    题目描述 有 $n$ 个箱子,每个箱子里有且仅有一把钥匙,每个箱子有且仅有一把钥匙可以将其打开.现在随机打开 $m$ 个箱子,求能够将所有箱子打开的概率. 题解 组合数学+概率dp 题目约定了每个点的 ...

  3. hihocoder 1075 : 开锁魔法III

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

  4. #1075 : 开锁魔法III

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

  5. Hiho #1075: 开锁魔法III

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

  6. 【整理】简单的数学期望和概率DP

    数学期望 P=Σ每一种状态*对应的概率. 因为不可能枚举完所有的状态,有时也不可能枚举完,比如抛硬币,有可能一直是正面,etc.在没有接触数学期望时看到数学期望的题可能会觉得很阔怕(因为我高中就是这么 ...

  7. hihoCode 1075 : 开锁魔法III

    时间限制:6000ms 单点时限:1000ms 内存限制:256MB 描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅 ...

  8. HDU5985 Lucky Coins 概率dp

    题意:给你N种硬币,每种硬币有Si个,有Pi 概率朝上,每次抛所有硬币抛起,所有反面的拿掉,问每种硬币成为最后的lucky硬币的概率. 题解:都知道是概率dp,但是模拟赛时思路非常模糊,很纠结,dp[ ...

  9. 概率dp总结

    终于做到概率dp题了,开个总结帖记录一下 首先是几篇论文:有关概率和期望问题的研究 做了这么多题,实际上没什么特别好总结的,就是搞清状态和转移,顺着写就行了,和基本dp差不多 概率是由过去到现在dp[ ...

随机推荐

  1. php简易实现计划任务

    index.php <?php function ceshi(){ $wan = file_get_contents('./wangt_index.txt',true); $jifen = $w ...

  2. Notepad++删除空行的多种实现办法

    Notepad++支持基础的正则表达式,同时由于自身丰富的插件和功能,所以删除空行或有空格的空行,有多种实现办法,条条大路通罗马,闪电博客抛砖引玉,供大家参考. 一.删除空行(不包括有空格类符号的空行 ...

  3. mysql_connect(): [2002] No such file or directory

    在mac中搭建php的开发环境 1. apach ---- 推荐用MAMP.你只要把你的php文件/项目放入到htdocs(/Applications/MAMP/htdocs)目录下,启动mamp,输 ...

  4. 【jQuery】 常用函数

    [jQuery] 常用函数 html() : 获取设置元素内的 html,包含标签 text() : 获取设置元素内的文本, 不包含标签 val() : 获取设置 value 值 attr() : 获 ...

  5. Clean Code 《代码整洁之道》前四章读书笔记

    第一章: 整洁的代码只做好一件事   减少重复代码   提高表达力   提早构建简单抽象   让营地比你来时更干净   第二章:有意义的命名 名副其实:如果名称需要注释来补充,就不算是名副其实.   ...

  6. Mac下用tomcat搭建下载服务器

    1.下载tomcat 去官方网址: http://tomcat.apache.org/ 下载最新版 2.下载解压后,自己可以随便放在哪个文件夹下,自己记得路径即可.比如Users/你的用户名/Docu ...

  7. appium + Python + iOS 滑屏方法(appium版本大于1.5)

    之前一直在搞android的自动化,滑动操作一直都用swipe(),比如: he1 = int(dr.get_window_size()['height'] * 0.8)he2 = int(dr.ge ...

  8. Leetcode代码补全——链表

    通过补全代码可以更深刻的体会到,链表就是一个存储方式,通过一单元的存储指向下一单元,而查看单元内容通过头部开始的指针依次遍历.这是leetcode里融合两个链表的题目,具体代码如下: #encodin ...

  9. 第二篇 Python初识别及变量名定义规范

    第一个Python程序 可以打开notepad或者其他文本编辑器,输入:print("Hello Python!"),将文件保存到任意盘符下,后缀名是  .py 两种python程 ...

  10. CSS3 :animation 动画

    CSS3动画分为二部份: 1.定义动画行为: 使用@keyframes定义动画行为,有两种方式: 方式一:仅定义动画起始样式,与动画结束样式 @keyframes (动画行为名称) { from {b ...