HDU3625:Examining the Rooms

18 篇文章 0 订阅
7 篇文章 0 订阅

HDU3625:Examining the Rooms

题目大意

传送门
在这里插入图片描述

思路

我们可以考虑,我们炸了i个门,形成了j个环的总数,因为如果我炸开一个环上一个点,我就可以连锁反应把这个环给一锅端了,所以 d p [ i ] [ j ] = ( i − 1 ) × d p [ i − 1 ] [ j ] + d p [ i − 1 ] [ j − 1 ] dp[i][j]=(i-1)\times dp[i-1][j]+dp[i-1][j-1] dp[i][j]=(i1)×dp[i1][j]+dp[i1][j1],我们发现这个东西就是第一类斯特林数,又因为第一个房间不能炸,然后概率就是 d p [ i ] [ j ] − d p [ i − 1 ] [ j − 1 ] ( 减 去 第 一 个 房 间 被 炸 了 的 总 数 ) n ! \frac{dp[i][j]-dp[i-1][j-1](减去第一个房间被炸了的总数)}{n!} n!dp[i][j]dp[i1][j1](),所以答案就是 ∑ i = 1 k d p [ n ] [ i ] − d p [ n − 1 ] [ i − 1 ] n ! \sum_{i=1}^{k}\frac{dp[n][i]-dp[n-1][i-1]}{n!} i=1kn!dp[n][i]dp[n1][i1]

代码被HDU针对

#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm> 
using namespace std;

#define Int register int
#define int long long
#define MAXN 35

int n,k;
int s[MAXN][MAXN];
int fac[MAXN];

void init()
{
	fac[0]=s[0][0]=1;
	for (Int i=1;i<=20;++i)
	{
		fac[i]=fac[i-1]*i;
		s[i][0]=0;s[i][i]=1;
		for (Int j=1;j<i;++j)	
			s[i][j]=s[i-1][j-1]+s[i-1][j]*(i-1);
	}
}

void read (int &x)
{
	x=0;char c=getchar();int f=1;
	while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
	x*=f;return;
}

void write (int x)
{
	if (x<0){x=-x;putchar('-');}
	if (x>9) write (x/10);
	putchar(x%10+'0');
}

signed main()
{
	init();
	int times;
	read (times);
	while (times--)
	{
		read (n),read (k);
		double ans=0;
		for (Int i=1;i<=k;++i)
			ans+=(s[n][i]-s[n-1][i-1])*1.0/fac[n];
		printf ("%.4lf\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值