解题思路:
题目比较难理解,大致题意就是一共有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[N][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; }
POJ 2096 Collecting Bugs(概率DP)
原文地址:http://blog.csdn.net/moguxiaozhe/article/details/43484509