• 【YBTOJ】守卫挑战


    题目大意:

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

    数据范围:(0leq Kleq2000,0leq Lleq Nleq 200,-1leq a_ileq1000,0leq p_ileq100)

    正文:

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

    搞定 (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;
    }
    
  • 相关阅读:
    java 深入技术三(List)
    java 深入技术二(Collection)
    java开发JDBC连接数据库详解
    数据库基础和JDBC
    java 深入技术一
    java入门 第三季4
    java入门 第三季3
    04-1. 水仙花数(20)
    04-0. 求符合给定条件的整数集(15)
    03-4. 成绩转换(15)
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/14304584.html
Copyright © 2020-2023  润新知