抛硬币 Flipping Coins(Gym - 101606F)

Here’s a jolly and simple game: line up a row of N identical coins, all with the heads facing

down onto the table and the tails upwards, and for exactly K times take one of the coins, toss it

into the air, and replace it as it lands either heads-up or heads-down. You may keep all of the

coins that are face-up by the end.

Being, as we established last year, a ruthless capitalist, you have resolved to play optimally to

win as many coins as you can. Across all possible combinations of strategies and results, what

is the maximum expected (mean average) amount you can win by playing optimally?

Input

One line containing two space-separated integers:

  N(1<=N<=400), the number of coins at your mercy;

  K(1<=K<=400), the number of flips you must perform.

Output

Output the expected number of heads you could have at the end, as a real number. The output

must be accurate to an absolute or relative error of at most 10-6.

----------------------------------------------------------------------------------------------------------------------

题意:给出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("%.8lf\n", ans);
32     }
33     return 0;
34 }

AC代码

原文地址:https://www.cnblogs.com/kang000/p/8571071.html

时间: 2024-10-23 15:12:02

抛硬币 Flipping Coins(Gym - 101606F)的相关文章

抛硬币的两种思维方式

抛硬币是经典统计学中最基础的案例,无论是理论还是实验,都证明了50%这个概率,而且抛的次数越多,越接近这个值. 我们来看看一下这个问答:(以下对话例子来源于塔勒布的<黑天鹅>) A:假设硬币是公平的,因为每次抛出硬币得到正面与反面的可能性都是相同的.我把它抛出了99次,每次都正好得到正面.那么,我下一次得到反面的概率是多大? 回答者1(统计学家):毫无疑问,当然是50%,因为统计学中的样本独立性,不管你前面得到了什么结果,与下一次的结果都无关,所以可能性依然是50%. 好吧,对于学过统计的人,

csu 1009 抛硬币

C - 抛硬币 CSU - 1009 James得到了一堆有趣的硬币,于是决定用这些硬币跟朋友们玩个小游戏.在一个N行M列的表格上,每一个第i行第j列的格子上都放有一枚James的硬币,抛该硬币正面朝上的概率为Pij,所有抛硬币事件两两之间是相互独立的. 现在,玩家在M列硬币中,从每一列里各选择1枚,共M枚,构成一组.如此重复选择N组出来,且保证被选择过的硬币不能再选.选好组之后,每组的M枚硬币各抛一次,如果都是正面朝上,则该组胜利,总分赢得1分:否则该组失败,总分不加也不减.请问,如果让你自行

模拟抛硬币(C语言实现)

实现代码: 1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int heads() 5 { 6 return rand() < RAND_MAX/2; 7 } 8 9 int main(int argc, char *argv[]) 10 { 11 int i,j,cnt; 12 int N = atoi(argv[1]), M = atoi(argv[2]); 13 int *f = malloc((N+1)*sizeof(int)

[AH/HNOI2017]抛硬币

题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个月,却一次都没有抽到 SSR,让他非常怀疑人生.勤勉的小 A 为了劝说小 B 早日脱坑,认真学习,决定以抛硬币的形式让小 B 明白他是一个彻彻底底的非洲人,从而对这个游戏绝望.两个人同时抛 b 次硬币,如果小 A 的正面朝上的次数大于小 B 正面朝上的次数,则小 A 获胜. 但事实上,小 A 也曾经沉迷过拉拉游戏,而且他一次 UR 也没有抽到过,所以他对于自

【刷题】BZOJ 4830 [Hnoi2017]抛硬币

Description 小A和小B是一对好朋友,他们经常一起愉快的玩耍.最近小B沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个月,却一次都没有抽到SSR,让他非常怀疑人生.勤勉的小A为了劝说小B早日脱坑,认真学习,决定以抛硬币的形式让小B明白他是一个彻彻底底的非洲人,从而对这个游戏绝望.两个人同时抛b次硬币,如果小A的正面朝上的次数大于小B正面朝上的次数,则小A获胜.但事实上,小A也曾经沉迷过拉拉游戏,而且他一次UR也没有抽到过,所以他对于自己的运气也没有太大把握.所以他决定在小

抛硬币问题

每次抛掷硬币正面向上和反面向上的概率是相同的 问题 1 :抛掷硬币 n 次,求连续 k 次正面向上的方案数有多少种 ? 一个比较好想的点子是直接 2^n 枚举,在这其中寻找符合要求的有多少种,复杂度爆表... 在计算连续 k 次正面向上的方案数可能并不太好算,那么就转换成 用总的方案数减去仅有连续小于 k 次的方案数 dp[i] 表示 到第 i 个位置仅存在小于连续 k 次正面向上的方案数 1 . 当 i < k 时, dp[i] = dp[i-1]*2 2 . 当 i == k 时, dp[i

用随机数列模拟抛硬币

先粘贴上代码 package djbc; import java.util.Random;import java.util.Scanner; public class Lian {public static void main(String[] args) {int i=0,k=0,t=0;  System.out.println("请输入要抛的次数");Scanner scan=new Scanner(System.in);//输入抛硬币的次数t=scan.nextInt();Ran

HZOI20190908模拟40 队长快跑,影魔,抛硬币 题解

题面:https://www.cnblogs.com/Juve/articles/11487699.html 队长快跑: 权值线段树与dp yy的不错 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int MAXN=1e5+5; int n,a[MAXN],b[

Gym 101606F - Flipping Coins - [概率DP]

题目链接:https://codeforc.es/gym/101606/problem/F 题解: 假设 $f[i][j]$ 表示抛 $i$ 次硬币,有 $j$ 个硬币正面朝上的概率. 所以只有两种挑选硬币的情况: 1.正面硬币数量为 $[0,n-1]$,选择反面硬币抛,则正面硬币数量比原本增加 $1$ 或者不变. 2.正面硬币数量为 $n$,随便选择一个硬币抛,则正面硬币数量比原本减少 $1$ 或者不变. 因此可得状态转移方程: 对于 $j<n$,有 f[i+1][j+1]+=f[i][j]*