【luogu CF1153F】Serval and Bonus Problem(期望)(DP)

Serval and Bonus Problem

题目链接:luogu CF1153F

题目大意

长度为 l 的线段,有 n 个区间端点随机分布,然后问你期望有多少长度被至少 k 个区间覆盖。

思路

首先这种随机分布的期望题考虑也把随机的时间弄成一个平均分布。
在这里就是我们可以理解为这 2 n 2n 2n 个端点是均匀分布在 l l l 上的,那每段长度就是 l 2 n + 1 \dfrac{l}{2n+1} 2n+1l

然后我们就可以考虑 DP,设 f i , j f_{i,j} fi,j i i i 个端点,当前有 j j j 个左端点没有匹配。
那没有匹配说明要延伸过去,那只要延伸过去的数量大于等于 k k k,就说明这个段是贡献的。

然后我们考虑每个位置放左端点还是右端点,注意如果是右端点你会选跟哪个左端点,所以要乘上 j j j

然后你考虑怎么计算答案,你前面保证了这个左端点,那右端点你也应该要保证吧。
那左右端点其实是一样的,所以你可以直接用 DP 的值,就是两个乘起来,然后左右端点匹配是一个阶乘。

然后你前面算的是方案你要除总方案才是概率,然后总方案是 f 2 n , 0 f_{2n,0} f2n,0

然后就可以啦。

代码

#include<cstdio>
#define ll long long
#define mo 998244353

using namespace std;

const int N = 2005;
int n, k, l;
ll f[N << 1][N], jc[N];

ll ksm(ll x, ll y) {
	ll re = 1;
	while (y) {
		if (y & 1) re = re * x % mo;
		x = x * x % mo; y >>= 1;
	}
	return re; 
}

ll clac(int n, int k) {
	f[0][0] = 1; ll ans = 0;
	for (int i = 0; i < 2 * n; i++) {
		for (int j = 0; j <= i && j <= n; j++) {
			(f[i + 1][j + 1] += f[i][j]) %= mo;
			if (j) (f[i + 1][j - 1] += f[i][j] * j % mo) %= mo;
		}
	}
	for (int i = 1; i <= 2 * n; i++)
		for (int j = k; j <= n; j++)
			(ans += f[i][j] * f[2 * n - i][j] % mo * jc[j]) %= mo;
	return ans * ksm(f[2 * n][0], mo - 2) % mo;
}

int main() {
	scanf("%d %d %d", &n, &k, &l); l = l * ksm(2 * n + 1, mo - 2) % mo;
	jc[0] = 1; for (int i = 1; i <= n; i++) jc[i] = jc[i - 1] * i % mo;
	printf("%lld", clac(n, k) * l % mo);
	
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值