HihoCoder 1075 开锁魔法III(概率DP+组合)
描述
一日,崔克茜来到小马镇表演魔法。
其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它。初始时,崔克茜将会随机地选择 k 个盒子用魔法将它们打开。崔克茜想知道最后所有盒子都被打开的概率,你能帮助她回答这个问题吗?
输入
第一行一个整数 T (T ≤ 100)表示数据组数。 对于每组数据,第一行有两个整数 n 和 k (1 ≤ n ≤ 300, 0 ≤ k ≤ n)。 第二行有 n 个整数 ai,表示第 i 个盒子中,装有可以打开第 ai 个盒子的钥匙。
输出
对于每组询问,输出一行表示对应的答案。要求相对误差不超过四位小数。
样例输入
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
样例输出
0.000000000
0.600000000
0.900000000
1.000000000
1,每个盒子都有一个入度和一个出度,以之前二分图拆点的经验来看,必然会形成很多个环。
2,每个环至少选择一个盒子。
3,每个环至少选择一个盒子的组合数,联想到母函数,组合数。
4.自由YY。可以DP,但是误差可能大一些。可以全部求出来再除,这样误差小一些。
(ps:学会了母函数再搞组合是要多一分灵感!弯的four)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
const int maxn=;
double c[maxn][maxn];
double a[maxn],b[maxn];
int loop[maxn],num[maxn],cnt,laxt[maxn],n;
void init()
{
cnt=;
for(int i=;i<=n;i++){
a[i]=b[i]=num[i]=loop[i]=laxt[i]=;
}
}
void getc()
{
int i,j;
for(i=;i<=;i++){
c[i][]=c[i][i]=1.0;
for(j=;j<i;j++) c[i][j]=c[i-][j]+c[i-][j-];
}
return ;
}
void geta()
{
int i,j,k;
for(i=;i<=num[];i++) a[i]=c[num[]][i],b[i]=0.0;
for(i=;i<=cnt;i++){
for(j=;j<=n;j++)
for(k=;k<=num[i];k++)
if(j+k<=n) b[j+k]+=a[j]*c[num[i]][k];//不是+1
for(j=;j<=n;j++){
a[j]=b[j];
b[j]=;
}
}
}
int main()
{
int i,j,T,k;
scanf("%d",&T);
getc();//组合数C
while(T--){
scanf("%d%d",&n,&k);
init();
for(i=;i<=n;i++) scanf("%d",&laxt[i]);
for(i=;i<=n;i++){//分组
if(!loop[i]){
++cnt;
for(j=i;;j=laxt[j]){
if(loop[j]) break;
loop[j]=cnt;
num[cnt]++;
}
}
}
geta();//保证每个环至少一个的母函数
printf("%.9lf\n",a[k]/c[n][k]);
}
return ;
}
HihoCoder 1075 开锁魔法III(概率DP+组合)的更多相关文章
- hihocoder 1075 : 开锁魔法III
描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...
- #1075 : 开锁魔法III
描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...
- Hiho #1075: 开锁魔法III
Problem Statement 描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜 ...
- hihoCode 1075 : 开锁魔法III
时间限制:6000ms 单点时限:1000ms 内存限制:256MB 描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅 ...
- hihocoder1075【开锁魔法】
hihocoder1075[开锁魔法] 题意是给你一个 \(1-n\) 的置换,求选 \(k\) 个可以遍历所有点的概率. 题目可以换个模型:有 \(n\) 个球,有 \(cnt\) 种不同的颜色,求 ...
- hrb——开锁魔法I——————【规律】
解题思路:从1到n的倒数之和. #include<stdio.h> #include<string.h> #include<algorithm> using nam ...
- 【bzoj5004】开锁魔法II 组合数学+概率dp
题目描述 有 $n$ 个箱子,每个箱子里有且仅有一把钥匙,每个箱子有且仅有一把钥匙可以将其打开.现在随机打开 $m$ 个箱子,求能够将所有箱子打开的概率. 题解 组合数学+概率dp 题目约定了每个点的 ...
- BZOJ 5004: 开锁魔法II 期望 + 组合
Description 题面:www.lydsy.com/JudgeOnline/upload/task.pdf Input Output 一般概率题有两种套路: 满足条件的方案/总方案. 直接求概率 ...
- Dice (III) 概率dp
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> ...
随机推荐
- LCS最长共同子序列
2017-09-02 15:06:57 writer:pprp 状态表示: f(n,m)表示s1[0..n]和s2[0..m]从0开始计数,最终结果是f(N-1,M-1)考虑四种情况: 1/ s1[n ...
- Spring MVC 方法注解拦截器
应用场景,在方法级别对本次调用进行鉴权,如api接口中有个用户唯一标示accessToken,对于有accessToken的每次请求可以在方法加一个拦截器,获得本次请求的用户,存放到request或者 ...
- CentOS7下Firewall常用命令
安装它,只需 yum install firewalld 如果需要图形界面的话,则再安装 yum install firewall-config 一.介绍 防火墙守护 firewalld 服务引入了一 ...
- MySQL5.7 半同步复制
一.概述 5.5与5.7的半同步复制可能存在差异,从MySQL5.5开始,MySQL以插件的形式支持半同步复制 异步:默认情况下,MySQL复制是异步的.主库在执行完客户端提交的事务后会立即将结果返给 ...
- 《Think in Java》(十二)通过异常处理错误
异常虽然简单,但是很有用!学完这一章还是发现 Java 异常还是有很多可学之处的,比如:异常说明,异常链等.
- Hive -hivevar 参数传递
命令行模式,或者说目录模式,可以使用hive 执行命令. 选项说明: -e : 执行短命令 -f : 执行文件(适合脚本封装) -S : 安静模式,不显示MR的运行过程 -hivevar : 传参数 ...
- for each/in/of的解释and example
for-of 循环:代码示例for (var value of myArray) {console.log(value);}循环的对象需为一个数组 无法记录索引 可以相应break.continue. ...
- 1.SpringMVC设计理念与DispatcherServlet
SpringMVC作为Struts2之后异军突起的一个表现层框架,正越来越流行,相信javaee的开发者们就算没使用过SpringMVC,也应该对其略有耳闻.我试图通过对SpringMVC的设计思想和 ...
- 这可能是最详细的 iOS 学习入门指南(含书目/文档/学习资料)
1 零基础小白如何进行 iOS 系统学习 首先,学习目标要明确: 其次,有了目标,要培养兴趣,经常给自己一些正面的反馈,比如对自己的进步进行鼓励,在前期小步快走: 再次,学技术最重要的一点就是多动手. ...
- Python 常用 PEP8 编码规范
Python 常用 PEP8 编码规范 代码布局 缩进 每级缩进用4个空格. 括号中使用垂直隐式缩进或使用悬挂缩进. EXAMPLE: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 ...