标签:pre closed 个数 多少 acm-icpc hide span challenge 情况
题目链接:https://www.jisuanke.com/contest/2870?view=challenges
题目大意:给出n个都正面朝下的硬币,操作m次,每次都选取k枚硬币抛到空中,求操作m次后,硬币向上的期望值。
思路:
1.期望跟概率还是有点不同的,期望要枚举出抛的所有的情况,然后求sigma(i * dp[][])
2.dp[i][j]表示进行i次操作后,有j枚硬币向上的概率。这样就可以求最后的硬币向上的期望了。
3.值得注意的是,预处理的组合数要开 double 型。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #define mem(a, b) memset(a, b, sizeof(a)) 4 5 double C[110][110];//组合数 6 double P[110]; //翻i个硬币的概率,因为正反都是 1 / 2,所以用一维数组表示 7 double dp[110][110]; //表示操作i次,有j枚硬币正面向上的概率 8 int n, m, k; 9 10 int main() 11 { 12 //预处理组合数 13 C[0][0] = 1; 14 for(int i = 1; i <= 100; i ++) 15 { 16 C[i][0] = 1; 17 for(int j = 1; j <= i; j ++) 18 { 19 C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; 20 } 21 } 22 //预处理i个硬币的概率 23 P[0] = 1.0; 24 for(int i = 1; i <= 100; i ++) 25 P[i] = 0.5 * P[i - 1]; 26 int T; 27 scanf("%d", &T); 28 while(T --) 29 { 30 mem(dp, 0); 31 dp[0][0] = 1.0; 32 scanf("%d%d%d", &n, &m, &k); 33 for(int i = 0; i < m; i ++)//枚举操作次数 34 { 35 for(int j = 0; j <= n; j ++)//枚举硬币正面向上的个数 36 { 37 if(dp[i][j] == 0) 38 continue; 39 for(int q = 0; q <= k; q ++)//枚举抛k枚硬币有多少枚硬币会朝上,枚举所有情况,才是求期望 40 { 41 if((n - j) >= k) 42 dp[i + 1][j + q] += dp[i][j] * C[k][q] * P[k]; 43 else 44 dp[i + 1][j + q - (k - (n - j))] += dp[i][j] * C[k][q] * P[k]; 45 } 46 } 47 } 48 double ans = 0.0; 49 for(int i = 0; i <= n; i ++) 50 { 51 ans += dp[m][i] * i; 52 } 53 printf("%.3lf\n", ans); 54 } 55 return 0; 56 }
ACM-ICPC 2017 Asia Urumqi A. Coins【期望dp】
标签:pre closed 个数 多少 acm-icpc hide span challenge 情况
原文地址:https://www.cnblogs.com/yuanweidao/p/10992250.html