Gym 101606 F-Flipping Coins(概率dp)
參考博客:http://www.cnblogs.com/kang000/p/8571071.html? (這篇博客寫的真的走心,ORZ)
?
題意
有n個硬幣排成一排,開始的時候所有的硬幣都是正面朝下,你必須要扔K次硬幣,每次選擇一個硬幣,如果你采取最優(yōu)策略,K次以后朝上的硬幣數(shù)的最大期望是多少?
分析
一臉懵逼兩臉懵逼三臉懵逼···
--------------------------------------------------------------------------
隨機變量X是指朝上的硬幣數(shù),當有N枚硬幣的時候,X=0,1,2,3....N
E(X)=1*p(1)+2*p(2)+....+n*p(n)。
要想求最大期望,我們在扔硬幣的時候要遵循一個策略:盡量扔正面朝下的硬幣
如果當前有0到n-1枚硬幣正面朝上,我們可以選擇正面朝下的硬幣來扔,扔完以后朝上硬幣數(shù)不變或者+1
如果當前有n枚硬幣正面朝上,我們只能選擇正面朝上的硬幣來扔,扔完以后朝上的硬幣數(shù)不變或者-1
-----------------------------------------------------------------------------------------------
令dp[i][j]為扔i次以后j枚硬幣朝上的概率
根據(jù)上面總結(jié)的規(guī)律,我們可以的到狀態(tài)轉(zhuǎn)移方程
當j<n的時候
dp[i+1][j]+=dp[i][j]*0.5
dp[i+1][j+1]+=dp[i][j]*0.5
當j=n的時候
dp[i+1][j+1]+=dp[i][j]*0.5
dp[i+1][j-1]+=dp[i][j]*0.5
這樣遞推出概率來以后遍歷一遍j求期望就好了~
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 6 using namespace std; 7 const int maxn=500; 8 double dp[maxn][maxn]; 9 int n,k; 10 int main(){ 11 scanf("%d%d",&n,&k); 12 memset(dp,0,sizeof(dp)); 13 dp[0][0]=1; 14 15 for(int i=0;i<k;i++){ 16 for(int j=0;j<=n;j++){ 17 if(j<n){ 18 dp[i+1][j]+=0.5*dp[i][j]; 19 dp[i+1][j+1]+=0.5*dp[i][j]; 20 } 21 if(j==n){ 22 dp[i+1][j]+=0.5*dp[i][j]; 23 dp[i+1][j-1]+=0.5*dp[i][j]; 24 } 25 } 26 } 27 /*for(int i=0;i<=k;i++){ 28 for(int j=0;j<=n;j++){ 29 printf("%d %d %f\n",i,j,dp[i][j]); 30 } 31 }*/ 32 double ans=0; 33 for(int i=1;i<=n;i++){ 34 ans+=dp[k][i]*i; 35 } 36 printf("%.6f",ans); 37 38 return 0; 39 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/LQLlulu/p/8886855.html
總結(jié)
以上是生活随笔為你收集整理的Gym 101606 F-Flipping Coins(概率dp)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【刷题记录】杂题记录
- 下一篇: Android java 多线程(三