poj 2096 Collecting Bugs

31 篇文章 0 订阅
2 篇文章 0 订阅

Problem

poj.org/problem?id=2096

vjudge.net/contest/151678#problem/Q

Reference

blog.csdn.net/xingyeyongheng/article/details/25179481

blog.csdn.net/zy691357966/article/details/46776199(概率dp入门)

www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html(概率dp总结 by kuangbin)

wenku.baidu.com/view/1c41152de2bd960590c677a8.html(《信息学竞赛中概率问题求解初探》by 梅诗珂)

wenku.baidu.com/view/90adb02acfc789eb172dc8a8.html(《浅析竞赛中一类数学期望问题的求解》 by 汤可因)

wenku.baidu.com/view/56147518a8114431b90dd81e.html(《有关概率和期望问题的研究》 by 鬲融)

Meaning

Ivan 每天找一个 bug。现有 s 个子系统、n 种 bug,在每一个子系统中找到 bug 的概率永远相同(因为有无数个,概率不变),找到任意种 bug 的概率也永远相同。

要求在每个子系统中都至少找到一个 bug、每个种类的 bug 至少找一个,求所需的天数的期望值。

Analysis

dp[i][j]:已在 i 个子系统中找到 bug,已找到 j 种 bug,为达目的仍需要的期望天数。

显然,对所有 i >= s、j >= n 的 dp[i][j],有:dp[i][j] = 0。

在 dp[i][j] 的状态下,再找一个 bug,可能转去 4 种状态:

1. dp[i+1][j+1]:在一个还没发现过 bug 的子系统中(新系统),找到一种还没发现过的 bug(新 bug),概率是:p1 = (s - i) * (n - j) / (n * s);

2. dp[i+1][j]:在一个还没发现过 bug 的子系统中(新系统),找到一种已经发现过的 bug(旧 bug),概率是:p2 = (s - i) * j / (n * s);

3. dp[i][j+1]:在一个已经发现过 bug 的子系统中(旧系统),找到一种还没发现过的 bug(新 bug),概率是:p3 = i * (n - j) / (n * s);

4. dp[i][j]:在一个已经发现过 bug 的子系统中(旧系统),找到一种已经发现过的 bug(旧 bug),概率是:p4 = i * j / (n * s)。

所以,dp[i][j] = p1 * dp[i+1][j+1] + p2 * dp[i+1][j] + p3 * dp[i][j+1] + p4 * dp[i][j] + 1

移项整理,有:dp[i][j] =  (p1 * dp[i+1][j+1] + p2 * dp[i+1][j] + p3 * dp[i][j+1] + 1) / (1 - p4)

Code

#include <stdio.h>
#define N 1000
#define S 1000

double dp[N+2][S+2] = {{0.0}};

int main()
{
    int n, s, i, j;
    scanf("%d%d", &n, &s);
    for(i=n; ~i; --i)
        for(j=s; ~j; --j)
            if(i != n || j != s)
			{
				int p1 = (n - i) * (s - j),
					p2 = (n - i) * j,
					p3 = i * (s - j),
					p4 = i * j;
				dp[i][j] = (
					p1 * dp[i+1][j+1] +
					p2 * dp[i+1][j] +
					p3 * dp[i][j+1] +
					n * s
				) / (n * s - p4);
			}
    printf("%.4f\n", dp[0][0]);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值