码迷,mamicode.com
首页 > 其他好文 > 详细

【YBTOJ】守卫挑战

时间:2021-01-21 10:45:31      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:double   lan   不同   成功   mat   范围   ret   个数   div   

题目大意:

\(n\) 项任务,有一个数 \(K\)。每一项任务成功的概率是 \(p_i\)(这里与原题目不同,原题目是百分之 \(p‘_i\),这里相当于 \(p_i=\frac{p‘_i}{100}\)),成功后会使 \(K\) 加上 \(a_i\)。问至少成功 \(l\) 次且最后 \(K\leq0\) 的概率是多少。

数据范围:\(0\leq K\leq2000,0\leq L\leq N\leq 200,-1\leq a_i\leq1000,0\leq p_i\leq100\)

正文:

这道题 \(K\leq2000\) 很搞人,但是我们发现其实 \(K\) 至多到 \(200\)。毕竟 \(a_i\) 最少是 \(-1\),就是最多加上 \(n\)\(-1\) 才会对结果有影响。那么我们确定了 \(K\) 最终的范围:\(-200\leq K\leq200\)

搞定 \(K\) 以后,我们设 \(f_{i,j,k}\) 表示前 \(i\) 个任务成功了 \(j\) 个当前的 \(K\)\(k\) 的概率。

得到转移方程:

\[f_{i,j,k}=f_{i-1,j,k}\cdot(1-p_i)+f_{i-1,j,k-a_i}\cdot p_i \]

很明显,\(f_{0,0,K}=1\)

代码:

double f[N][N][N * 2];
int a[N];
double p[N], ans;
int n, l, K;

int main()
{
	scanf ("%d%d%d", &n, &l, &K);
	for (int i = 1; i <= n; i++)	
		scanf ("%lf", &p[i]), p[i] /= 100.0;
	for (int i = 1; i <= n; i++)
		scanf ("%d", &a[i]), a[i] = a[i] > 200? 200: a[i];
	f[0][0][K + 200] = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 0; j <= i; j++)
			for (int k = -200; k <= 200; k++)
				f[i][j][k + 200] = j > 0? f[i - 1][j][k + 200] * (1.0 - p[i]) + f[i - 1][j - 1][k - a[i] + 200] * p[i]: f[i - 1][j][k + 200] * (1.0 - p[i]);
	for (int i = l; i <= n; i++)
		for (int k = 200; k <= 400; k++)
			ans += f[n][i][k];
	printf ("%.6lf", ans);
	return 0;
}

【YBTOJ】守卫挑战

标签:double   lan   不同   成功   mat   范围   ret   个数   div   

原文地址:https://www.cnblogs.com/GJY-JURUO/p/14304584.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!