标签:code any require its blog ber iostream category iter
1 2
3.0000
题意:某公司请人去找程序的 bugs ,他每天可以找出一个bug 。bugs一共有 n 种,程序有 s 个子系统(0 < n, s <= 1 000)
要使每一个子系统至少有一个bug,并且所有种类的bug也至少找出一个的天数期望是多少?(精确到小数后4位)
入门概率dp:
dp[i][j] 代表的状态是有 i 种bug种类至少有一个,j 个子系统找出至少有一个bug
那么,再过一天,可能发生的情况有 4 种: (pi 指发生这种事情的概率)
找到一个已经出现过的种类的bug,并且在已经找出bug的子系统里面 P1 * dp[i][j]
找到一个未出现过的种类的bug,并且在已经找出bug的子系统里面 P2 * dp[i+1][j]
找到一个已经出现过的种类的bug,并且不在已经找出bug的子系统里面 P3 * dp[i][j+1]
找到一个是既未出现过的种类的bug,又不在已经找出bug的子系统里面 P4 * dp[i+1][j+1]
那么,就得出转移方程:
dp[i][j] = P1 * dp[i][j] + P2 * dp[i+1][j] + p3 * dp[i][j+1] + p4 * dp[i+1][j+1] + 1 (+1 是因为要过一天)
将它化简,合并掉两边的 dp[i][j]
显然 dp [n][s]=0
然后从 i = n , j = s 逆推到 i=0,j=0 dp[0][0]即为答案
1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 using namespace std; 5 #define MAXN 1010 6 7 double dp[MAXN][MAXN]; 8 9 int main() 10 { 11 int n,s; 12 while(scanf("%d%d",&n,&s)!=EOF) 13 { 14 memset(dp,0,sizeof(dp)); 15 dp[n][s]=0.0; 16 for (int i=n;i>=0;i--) 17 { 18 for (int j=s;j>=0;j--) 19 { 20 if (i==n&&j==s) continue; 21 dp[i][j]=(n*s+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-i*j);//注意数据类型的隐式转换 22 } 23 } 24 printf("%.4lf\n",dp[0][0]); 25 } 26 return 0; 27 }
标签:code any require its blog ber iostream category iter
原文地址:http://www.cnblogs.com/haoabcd2010/p/6700483.html