您的位置:首页 > 其它

POJ 2096 Collecting Bugs(概率DP)

2015-02-04 12:24 477 查看
解题思路:

题目比较难理解,大致题意就是一共有N种bugs,分别属于S个子系统,求找到N种BUG并且每种子系统的bug都被找到所需要的天数的数学期望。

dp[i][j]表示找到 i 种bug 属于 j 个子系统到 目标状态所需要的数学期望。dp[i][j]可以由四种状态转移而来。

(i * j) / (n * s) * d[i][j];

 (n - i) * j / (n * s) * dp[i+1][j];

 i * (s - j)/(n * s) * dp[i][j + 1];

(n - i) * (s - j) / (n * s) * dp[i+1][j+1];

因此

dp[i][j] = (i * j) / (n * s) * d[i][j] +  (n - i) * j / (n * s) * dp[i+1][j] +  i * (s - j)/(n * s) * dp[i][j + 1] + (n - i) * (s - j) / (n * s) * dp[i+1][j+1] + 1;

+1是指需要加上这次bug需要的天数。

整理得:

 dp[i][j] = ((N-i)*j*dp[i+1][j] + i*(S-j)*dp[i][j+1] + (N-i)*(S-j)*dp[i+1][j+1] + N*S)/(N * S - i * j);

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
const int maxn = 1000 + 10;
double dp[maxn][maxn];
int main()
{
int N, S;
while(scanf("%d%d", &N, &S)!=EOF)
{
dp
[S] = 0;
for(int i=N;i>=0;i--)
{
for(int j=S;j>=0;j--)
{
if(i == N && j == S)
continue;
dp[i][j] = ((N-i)*j*dp[i+1][j] + i*(S-j)*dp[i][j+1] + (N-i)*(S-j)*dp[i+1][j+1] + N*S)/(N * S - i * j);
}
}
printf("%.4f\n", dp[0][0]);
}
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM dp