【组合数学:第一类斯特林数】【HDU3625】Examining the Rooms
Examining the Rooms
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1138 Accepted Submission(s): 686
one key in each room, and all the possible distributions are of equal possibility. For example, if N = 3, there are 6 possible distributions, the possibility of each is 1/6. For convenience, we number the rooms from 1 to N, and the key for Room 1 is numbered
Key 1, the key for Room 2 is Key 2, etc.
To examine all the rooms, you have to destroy some doors by force. But you don’t want to destroy too many, so you take the following strategy: At first, you have no keys in hand, so you randomly destroy a locked door, get into the room, examine it and fetch
the key in it. Then maybe you can open another room with the new key, examine it and get the second key. Repeat this until you can’t open any new rooms. If there are still rooms un-examined, you have to randomly pick another unopened door to destroy by force,
then repeat the procedure above, until all the rooms are examined.
Now you are only allowed to destroy at most K doors by force. What’s more, there lives a Very Important Person in Room 1. You are not allowed to destroy the doors of Room 1, that is, the only way to examine Room 1 is opening it with the corresponding key. You
want to know what is the possibility of that you can examine all the rooms finally.
3
3 1
3 2
4 2
0.3333
0.6667
0.6250HintSample Explanation When N = 3, there are 6 possible distributions of keys: Room 1 Room 2 Room 3 Destroy Times
#1 Key 1 Key 2 Key 3 Impossible
#2 Key 1 Key 3 Key 2 Impossible
#3 Key 2 Key 1 Key 3 Two
#4 Key 3 Key 2 Key 1 Two
#5 Key 2 Key 3 Key 1 One
#6 Key 3 Key 1 Key 2 One In the first two distributions, because Key 1 is locked in Room 1 itself and you can’t destroy Room 1, it is impossible to open Room 1.
In the third and forth distributions, you have to destroy Room 2 and 3 both. In the last two distributions, you only need to destroy one of Room 2 or Room
递推关系的说明:
考虑第p个物品,p可以单独构成一个非空循环排列,这样前p-1种物品构成k-1个非空循环排列,方法数为s(p-1,k-1);
也可以前p-1种物品构成k个非空循环排列,而第p个物品插入第i个物品的左边,这有(p-1)*s(p-1,k)种方法。
边界条件 s(x,0)=0;s(x,x)=1;
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=20;
long long f[25],stir[25][25];
int solve()
{
int i,j;
f[0]=1;
for(i=1;i<=maxn;i++)
f[i]=i*f[i-1];
//因为N有N!种排列顺序,这作为总数
//计算概率
for(i=1;i<=maxn;i++)
stir[i][0]=0;
stir[1][1]=1;
for(i=1;i<=maxn;i++)
for(j=1;j<=i;j++)
{
if(i==j)
stir[i][j]=1;
else
stir[i][j]=stir[i-1][j-1]+(i-1)*stir[i-1][j];
}
for(i=1;i<=maxn;i++)
for(j=1;j<=maxn;j++)
if(stir[i][j]<0)
stir[i][j]=-stir[i][j];
return 0;
}
int main()
{
int cas,n,i,k;
long long sum;
solve();
scanf("%d",&cas);
while(cas--)
{
scanf("%d %d",&n,&k);
sum=0;
for(i=1;i<=k;i++)
sum+=stir[n][i]-stir[n-1][i-1];
printf("%.4lf\n",1.0*sum/f[n]);
//因为写成printf("%.4lf\n",(double)sum/f[n]);
//run time error! 下次一定记好了!
}
return 0;
}
接下来是我的方法!
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
using namespace std;
long long H[21];
long long F[21][21];
long long T[21];
long long C[21][21];
void CLT(int n,int len)
{
long long tot=n;
long long k=1;
for(int i=1;i<=len;i++)
{
if(T[i]==1)
{
k*=C[tot-1][1];
tot-=T[i];
}
else
{
k*=(C[tot][T[i]]*H[T[i]-1]);
tot-=T[i];
}
}
tot=1;
T[len+1]=0;
for(int i=2;i<=len+1;i++)
{
if(T[i]==T[i-1])
{
tot++;
}
else
{
k=k/H[tot];
tot=1;
}
}
F[n][len]+=k;
}
int getxulie(int n,long long tot,int prev,int len,int deep)
{
T[deep]=prev;
tot+=prev;
if(deep==len)
if(tot==n)
{
CLT(n,len);
return 1;
}
else
return 0;
for(int i=prev;i<=n-len+1;i++)
getxulie(n,tot,i,len,deep+1);
return 0;
}
void YCLYCL()
{
H[0]=1;
for(int i=1;i<=20;i++)
{
H[i]=H[i-1]*i;
}
for(int i=1;i<=20;i++)
C[i][0]=1;
C[1][1]=1;
for(int i=2;i<=20;i++)
for(int j=1;j<=i;j++)
{
C[i][j]=C[i-1][j-1]+C[i-1][j];
}
}
void YCL()
{ YCLYCL();
for(int i=2;i<=20;i++)
for(int j=1;j<=i;j++)
{
for(int k=1;k<=i-j+1;k++)
{
memset(T,0,sizeof(T));
getxulie(i,0,k,j,1);
}
}
for(int i=2;i<=20;i++)
for(int j=1;j<=i;j++)
{
F[i][j]+=F[i][j-1];
}
}
void inin()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
int main()
{
//inin();
YCL();
int K;
cin>>K;
int a;int b;
while(K--)
{
cin>>a>>b;
printf("%.4lf\n",((double)F[a][b]/(double)H[a]));
}
}
【组合数学:第一类斯特林数】【HDU3625】Examining the Rooms的更多相关文章
- [HDU 3625]Examining the Rooms (第一类斯特林数)
[HDU 3625]Examining the Rooms (第一类斯特林数) 题面 有n个房间,每个房间有一个钥匙,钥匙等概率的出现在n个房间内,每个房间中只会出现且仅出现一个钥匙.你能炸开门k次, ...
- hdu 3625 Examining the Rooms —— 第一类斯特林数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3625 学习斯特林数:https://blog.csdn.net/qq_33229466/article/d ...
- HDU3625(SummerTrainingDay05-N 第一类斯特林数)
Examining the Rooms Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 【Luogu4609】建筑师(第一类斯特林数,组合数学)
[Luogu4609]建筑师(组合数学) 题面 洛谷 题解 首先发现整个数组一定被最高值切成左右两半,因此除去最高值之后在左右分开考虑. 考虑一个暴力\(dp\) ,设\(f[i][j]\)表示用了\ ...
- HDU 4372 Count the Buildings——第一类斯特林数
题目大意:n幢楼,从左边能看见f幢楼,右边能看见b幢楼 楼高是1~n的排列. 问楼的可能情况 把握看到楼的本质! 最高的一定能看见! 计数问题要向组合数学或者dp靠拢.但是这个题询问又很多,难以dp ...
- 【HDU 4372】 Count the Buildings (第一类斯特林数)
Count the Buildings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- 如何快速求解第一类斯特林数--nlog^2n + nlogn
目录 参考资料 前言 暴力 nlog^2n的做法 nlogn的做法 代码 参考资料 百度百科 斯特林数 学习笔记-by zhouzhendong 前言 首先是因为这道题,才去研究了这个玩意:[2019 ...
- 【2019雅礼集训】【CF 960G】【第一类斯特林数】【NTT&多项式】permutation
目录 题意 输入格式 输出格式 思路 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a, ...
- CF960G Bandit Blues 第一类斯特林数、NTT、分治/倍增
传送门 弱化版:FJOI2016 建筑师 由上面一题得到我们需要求的是\(\begin{bmatrix} N - 1 \\ A + B - 2 \end{bmatrix} \times \binom ...
随机推荐
- Oracle 10g轻量级客户端安装[转]
http://www.oracle.com/technetwork/cn/topics/winsoft-095945-zhs.html oracle技术官方网 http://www.oracle.co ...
- Android应用程序进程启动过程的源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址: http://blog.csdn.net/luoshengyang/article/details/6747696 Android 应用程序框架层创 ...
- 改动mac环境变量,并配置gradle
由于项目中要用到gradle命令,可是没有配置环境变量.这里记录一下解决过程. 过程例如以下: 1. 启动终端Terminal 2. 进入当前用户的home文件夹 输入cd ~ 3. 创建.bash_ ...
- C#中的一种按日期分文件夹的日志写法
众所周知,日志是调试程序的有效途径,有一个好的日志代码,是一个程序小猿梦寐以求的. 以下是我结合网上资源自己总结的一小段代码,请笑纳: 转载请注明来源: http://www.cnblogs.com/ ...
- java面试大全
JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...
- PHP session 跨子域问题总结
Session主要分两部分: 一个是Session数据,该数据默认情况下是存放在服务器的tmp文件下的,是以文件形式存在 另一个是标志着Session数据的Session Id,Session ID, ...
- Cisco cmd命令(三)动态路由协议
路由选择协议:1.矢量距离协议 2.链路状态协议 RIP路由选择协议:1.使用矢量距离协议 2.RIPv1只能使用有类路由 3.RIPv2可以使用无类路由 路由更新定时器:用于将路由器本身完整的路由选 ...
- 使用Battery Historian(android 5.0)
http://hukai.me/android-performance-battery/可以先参考这篇文章 1$ adb shell dumpsys batterystats > xxx.txt ...
- hdu120118岁生日
Problem Description Gardon的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所 ...
- javascript sort排序
var arr = [5,32,28,66,2,15,3]; arr.sort(function(a1,a2){ return a1-a2; //a2-a1 输入倒序 }); console.log( ...