原题:http://poj.org/problem?id=2096
题意:
有n类bug,s个子系统,bug数量不限,每天只能发现一个bug;
问在s个子系统中发现n类bug所需要的天数的期望;
思路:
dp[i][j]表示在j个子系统中发现i类bug所需天数的期望,dp[n][s] = 0,每次发现bug有四种情况:
1)在已经发现的子系统和bug种类中,即dp[i][j],概率为p1 = (i/n)*(j/s);
2)在已经发现的子系统中发现新的bug种类,即dp[i+1][j],概率为p2 = (1-i/n)*(j/s);
3)在新的子系统中发现已有的bug种类,即dp[i][j+1],概率为p3 = (i/n)*(1-j/s);
4)在新的子系统中发现新的bug种类,即dp[i+1][j+1],概率为p4 = (1-i/n)*(1-j/s);
所以状态转移方程为dp[i][j] = dp[i][j]*p1+dp[i+1][j]*p2+dp[i][j+1]*p3+dp[i+1][j+1]*p4+1;
#include<stdio.h>
#include<string.h>
double dp[1100][1100];
double p1, p2, p3, p4;
int n, s;
int main()
{
while(scanf("%d%d", &n, &s)!=EOF)
{
memset(dp, 0, sizeof(dp));
for(int i = n;i>=0;i--)
{
for(int j = s;j>=0;j--)
{
if(i == n && j == s)
continue;
p1 = 1.0*i*j/(s*n);
p2 = 1.0*(n-i)*j/(s*n);
p3 = 1.0*i*(s-j)/(s*n);
p4 = 1.0*(n-i)*(s-j)/(s*n);
dp[i][j] = (dp[i+1][j]*p2+dp[i][j+1]*p3+dp[i+1][j+1]*p4+1)/(1-p1);
}
}
printf("%.4f\n", dp[0][0]);
}
return 0;
}