Problem F Flipping Coins

Problem F Flipping Coins

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 .

Sample Input 1 :2 1

Sample Output 1: 0.5

Sample Input 2 :2 2

Sample Output 2: 1

Sample Input 3 :3 2

Sample Output 3 :1.25

Sample Input 4 :6 10

Sample Output 4:4.63476563

Sample Input 5 :6 300

Sample Output 5:5.5

题目描述:

开始n个硬币面朝下,要硬币朝上越多,赢面越大。正好翻够k次。问赢面最大的期望。

分析:

dp[ i ] [ j ]表示翻了i次,j个硬币朝上的概率。在这个状态下翻一个硬币,因为要尽可能多的朝上,所以肯定时翻反面的硬币。所以状态变到dp[ i+1 ] [ j+1 ]的概率为1/2,变到dp[ i+1 ] [ j ]为1/2。

等到n面全部朝上的时候,如果还要继续翻,只能翻已经朝上的,这时变成反面dp[ i+1 ] [ n-1]概率为1/2,保持不变为dp[ i+1 ] [ n ]也是1/2。如果变成dp[ i+1 ] [ n-1]状态,可以继续转移到dp[ i+1 ] [ n ]状态。

最后算期望,分别把他概率*正面朝上个数就是了。

代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
int main()
{
    int n,k;
    cin>>n>>k;
    double dp[406][406];
    memset(dp,0,sizeof dp);
    dp[0][0]=1;
    for(int i=1;i<=k;i++)
    {
        for(int j=0;j<n;j++)
        {
            double a=dp[i-1][j]/2;
            dp[i][j+1]+=a;
            dp[i][j]+=a;
        }
        //n面朝上时 
        dp[i][n-1]+=dp[i-1][n]/2;//翻到一个反面 
        dp[i][n]+=dp[i-1][n]/2;//保持n面朝上 
    }
    double ans=0;
    for(int i=0;i<=n;i++) ans+=dp[k][i]*i;
    printf("%f\n",ans);
    return 0;
}
 

 

posted on 2020-03-12 13:28  Aminers  阅读(216)  评论(0编辑  收藏  举报

导航