描述

一日,崔克茜来到小马镇表演魔法。

其中有一个节目是开锁咒:舞台上有 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+组合)的更多相关文章

  1. hihocoder 1075 : 开锁魔法III

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

  2. #1075 : 开锁魔法III

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

  3. Hiho #1075: 开锁魔法III

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

  4. hihoCode 1075 : 开锁魔法III

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

  5. hihocoder1075【开锁魔法】

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

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

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

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

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

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

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

  9. Dice (III) 概率dp

    #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> ...

随机推荐

  1. [Network Architecture]Xception 论文笔记(转)

    文章来源 论文:Xception: Deep Learning with Depthwise Separable Convolutions 论文链接:https://arxiv.org/abs/161 ...

  2. MATLAB 图形图像处理

    theme: MATLAB author: pprp date: 2018/2/2 --- MATLAB 图形图像处理 二维绘图命令 plot 线性空间 plot(t,[x1,x2,x3]) : 在同 ...

  3. Python学习札记(十五) 高级特性1 切片

    参考: 高级特性 切片 Note 1.掌握了Python的基础语法之后,就可以写出很多很有用的程序了,比如打印1-90的奇数: #!/usr/bin/env python3 L = [] n = 1 ...

  4. C# Winform实现手机号码归属地查询工具

    摘要:本文介绍使用C#开发基于Winform的手机号码归属地查询工具,并提供详细的示例代码供参考. 一.需求描述 输入正确的手机号码,查询该号码的归属地和其他相关信息. 二.需求分析 1.实现手机号码 ...

  5. centos mysql忘记密码

    1.停止mysql 服务:service mysqld stop; 2.vim命令打开mysql配置文件my.cnf(位置一般为:/etc/my.cnf) 3.在mysqld进程配置文件中添加skip ...

  6. web.xml上下文初始化参数

    1.在web.xml文件中配置上下文参数 <!--<context-param>标签声明上下文初始化参数, --> <!-- 上下文初始化的参数可以被应用程序用所有ser ...

  7. mac 下 安装 mongodb

    使用brew安装,不过brew不再更新, 通过 sudo chown -R $(whoami):admin /usr/local 这条语句终端有提醒的 xcode-select --install 需 ...

  8. js 光标选中 操作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Gtk基础学习总结(一)

    第一个GTK程序例子: #include <stdio.h> #include <gtk/gtk.h> int main(int argc, char *argv[]) { g ...

  10. JS代码大全(都是网上看到自己整理的)

    事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture();  event.srcE ...