标签:
题目链接:http://poj.org/problem?id=2096
题目大意:有n种bug,有s个子系统。每天能够发现一个bug,属于一个种类并且属于一个子系统。问你每一种bug和每一个子系统都发现bug需要多少天。
设dp[i][j]为现在发现了i种bug,在j个子系统内,到目标状态需要的期望天数。
则dp[n][s] = 0,因为已经发现了n种bug在s个子系统内,不需要额外的天数了。
dp[i][j]可以转移到如下状态:
dp[i][j]:新发现的bug在已经发现的i种,已经发现的j个子系统内。概率为: (i/n)*(j/s)
dp[i+1][j]:新发现的bug在没有发现的种类中,但是在已经发现的j个子系统内。概率为 ( (n-i)/n ) * (j/s)
dp[i][j+1]:新发现的bug在已经发现的种类中,但是不在已经发现的j个子系统内。概率为 (i/n)*((s-j)/s)
dp[i+1][j+1]:新发现的bug既不在已经发现的种类中,并且也不在已经发现的j个子系统内。概率为 ( (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/n)*((s-j)/s) + dp[i+1][j+1] * ( (n-i)/n ) * ( (s-j)/s ) + 1
1 ///#pragma comment(linker, "/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <cmath> 10 #include <numeric> 11 #include <iterator> 12 #include <iostream> 13 #include <cstdlib> 14 #include <functional> 15 #include <queue> 16 #include <stack> 17 #include <string> 18 #include <cctype> 19 using namespace std; 20 #define PB push_back 21 #define MP make_pair 22 #define SZ size() 23 #define ST begin() 24 #define ED end() 25 #define CLR clear() 26 #define ZERO(x) memset((x),0,sizeof(x)) 27 typedef long long LL; 28 typedef unsigned long long ULL; 29 typedef pair<int,int> PII; 30 const double EPS = 1e-8; 31 32 const int MAX_N = 1111; 33 int n,s; 34 double f[MAX_N][MAX_N]; 35 36 int main(){ 37 while(~scanf("%d%d",&n,&s)){ 38 f[n][s] = 0.0; 39 for(int i=n;i>=0;i--){ 40 for(int j=s;j>=0;j--){ 41 if( n*s==i*j ) continue; 42 f[i][j] = 1.0*(f[i+1][j]*(n-i)*j+f[i][j+1]*i*(s-j)+f[i+1][j+1]*(n-i)*(s-j)+n*s)/(n*s-i*j); 43 } 44 } 45 printf("%.4f\n",f[0][0]); 46 } 47 48 return 0; 49 }
[POJ2096] Collecting Bugs (概率dp)
标签:
原文地址:http://www.cnblogs.com/llkpersonal/p/4558355.html