poj 2096 Collecting Bugs

一道用动态规划求数学期望的题目
首先给定dp[i][j]的含义:它表示在已经找到属于j个系统的i个bug时的期望值,也就是还需要多少天才能完成任务。这样的话就有dp[n][s] = 0;那么我们要求的就是dp[0][0].
而且,dp[i][j]可以生成dp[i+1][j+1],dp[i+1][j],dp[i][j+1],dp[i][j]四种状态
生成dp[i+1][j+1]的概率为p1 = (n-i)*(s-j)/(n*s),表示在剩下的(s-j)个系统中选择剩下(n-i)个的概率;下解释可以类似推导,
生成dp[i+1][j]的概率为p2 = (n-i)*j/(n*s);
生成dp[i][j+1]的概率为p3 = i*(s-j)/(n*s);
生成dp[i][j]的概率为p4 = i*j/(n*s);
所以有公式:dp[i][j] = p1 * (dp[i+1][j+1] + 1) + p2 * (dp[i+1][j] + 1) + p3 * (dp[i][j+1] + 1) + p4 * (dp[i][j]+1);//公式中的+1代表本次的操作
合并下就得到代码中的公式了。
代码:
#include <iostream>
#include <cstdio>
using namespace std;
int n, s;
double dp[1005][1005];
int main() { int i, j;
double ns;
scanf( "%d%d" , &n , &s );
dp[n][s] = 0.0;
ns = n * s;
for( i = n; i >= 0; --i )
for( j = s; j >= 0; --j )
{
if( i != n || s != j )
dp[i][j] = ( ( n - i ) * ( s - j ) * dp[i+1][j+1] + ns + ( n - i ) * j * dp[i+1][j] + i * ( s - j ) * dp[i][j+1] ) / ( ns - ( i * j ) );
}
printf( "%.4f\n" , dp[0][0] );
return 0;
}
转自 http://blog.sina.com.cn/s/blog_86a9d9720100zlxr.html,我觉得很不错,介绍的很清楚。

你可能感兴趣的:(数学期望)