我是靠谱客的博主 幽默百褶裙,最近开发中收集的这篇文章主要介绍抛硬币 Flipping Coins(Gym - 101606F)(DP),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述



题意:给出N个硬币,开始均反面朝上。每次挑出其中一个抛,连续K次,求正面朝上的最大数学期望。
----------------------------------------------------------------------------------------------------------------------

由于是求最大数学期望,所以每次抛硬币即要优先选择反面硬币

所以只有两种挑选硬币的情况:

  1.正面数量为 0 ~ n-1 ,选择反面硬币抛,抛出结果正面数量比原本 +1 或 不变

  2.正面数量为 n,只能够选择正面硬币抛,抛出结果正面数量比原本 -1 或 不变
----------------------------------------------------------------------------------------------------------------------

设 dp[i][j] 表示: 第 i 次抛硬币后, j 个硬币正面朝上的概率

  1.当 j < n 时,dp[i][j]的概率一分为二,各给dp[i+1][j]dp[i+1][j+1],即

for(int j=0;j<n;j++){
dp[i+1][j]+=dp[i][j]/2;
dp[i+1][j+1]+=dp[i][j]/2;
}

  2.当 j == n 时,dp[i][j]的概率一分为二,各给dp[i+1][j]dp[i+1][j-1],即

dp[i+1][n]+=dp[i][n]/2;
dp[i+1][n-1]+=dp[i][n]/2;

如此即可求出n个硬币抛k次的各个正面朝上的概率,最后求数学期望即可

附:n=2,k=4时的dp转移表格:

技术分享图片

技术分享图片
 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #include <iostream>
 6 #include <queue>
 7 #include <stack>
 8 #include <functional>
 9 #define INF 0x3f3f3f3f
10 using namespace std;
11 typedef long long ll;
12 double dp[410][410], ans;
13 int main(){
14
int n, k;
15
while (~scanf("%d %d", &n, &k)){
16
for (int i = 0; i <= 400; i++)
17
for (int j = 0; j <= 400; j++)
18
dp[i][j] = 0;
19
dp[0][0] = 1;
20
for (int i = 0; i < k; i++){
21
for (int j = 0; j < n; j++){
22
dp[i + 1][j] += dp[i][j] * 0.5;
23
dp[i + 1][j + 1] += dp[i][j] * 0.5;
24 
}
25
dp[i + 1][n] += dp[i][n] * 0.5;
26
dp[i + 1][n - 1] += dp[i][n] * 0.5;
27 
}
28
ans = 0;
29
for (int i = 1; i <= n; i++)
30
ans += i*dp[k][i];
31
printf("%.8lfn", ans);
32 
}
33
return 0;
34 }

最后

以上就是幽默百褶裙为你收集整理的抛硬币 Flipping Coins(Gym - 101606F)(DP)的全部内容,希望文章能够帮你解决抛硬币 Flipping Coins(Gym - 101606F)(DP)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部