http://poj.org/problem?id=2096
深深的被这个题给坑了,题意叙述的就比较麻烦。最纠结的是在输出的时候用%.4lf就是WA,用%.4f就AC了,不明白两者之间有什么细微的差别。
题意:给n个bug,s个子系统,某人一天会发现一个bug,这个bug属于某种类型的bug,发生在某个子系统上,这样dp[i][j]表示的是j个子系统中找到了i个bug,这样概率应该为i / n * j / s
求找到n中bug,且存在每个子系统中,这样所需天数的期望。
解法:这样会存在四种状态,
dp[i][j] 找到一个bug属于j个系统中的i类,概率为 i / n * j / s
dp[i + 1][j] 找到一个新的bug不属于之前找到的i类,但是属于j个子系统中 概率( n - i )/ n * j / s
dp[i][j + 1] 找到一个bug属于i类中,但是属于新的子系统中 概率 i / n * ( s - j ) / n
dp[i + 1][j + 1] 找到一个新的bug,属于新的子系统中,概率 ( n - i ) / n * ( s - j ) / s
这样 dp[i][j] = dp[i][j] * i / n * j / s + dp[i + 1][j] * ( n - i ) / n * j / s + dp[i][j + 1] * i * ( s - j ) / s + dp[i + 1][j + 1] * ( n - i) / n * ( s - j ) / s + 1; ( 化简略)
/*************************************************************************
> File Name: poj2096.cpp
> Author: AcToy
> Mail: ycsgldy@163.com
> Created Time: 2013年07月18日 星期四 12时54分04秒
************************************************************************/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef unsigned int u32;
typedef long long i64;
typedef unsigned long long u64;
typedef vector<int> IV;
typedef vector<bool> BV;
typedef pair<int,int> II;
typedef vector<II> IIV;
#define For(t,v,c) for(t::const_iterator v=c.begin(); v!=c.end(); ++v)
const int INF = 0x7FFFFFFF;
const double eps = 1E-10;
const double PI = acos(-1);
const int maxn = 1010;
int n, s;
double dp[maxn][maxn];
int main()
{
while(scanf("%d%d", &n, &s) == 2) {
dp[n][s] = 0;
for(int i = n; i >= 0; --i)
for(int j = s; j >= 0; --j) {
if(i == n && s == j) continue;
double tmp = n * s - i * j;
dp[i][j] = (dp[i + 1][j] * (n - i) * j + dp[i][j + 1] * i * (s - j) + dp[i + 1][j + 1] * (n - i) * (s - j) + n * s) / tmp;
}
printf("%.4f\n", dp[0][0]);
}
return 0;
}