概率DP 2017 ICPC 乌鲁木齐 A Coins

Posted qingjiuling

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了概率DP 2017 ICPC 乌鲁木齐 A Coins相关的知识,希望对你有一定的参考价值。

题目链接:https://nanti.jisuanke.com/t/40512

题意:n个硬币,初始全是反面朝上,抛m次,每次抛k个,求最好情况硬币向上个数的期望

一个比较好的概率DP的总结:https://blog.csdn.net/myjs999/article/details/81022546

分析:很明显当硬币反面朝上次数大于k,直接抛这些,小于k时,这些反面朝上全部取的,不够的加正面朝上的,dp[i][j]表示抛i次后正面朝上有j个的概率,枚举每次抛的硬币里面正面朝上有t个,状态转移方程就是dp[i+1]]j+t]=dp[i][j]*(1/2)^k*Ctk(t个里面选k个正面朝上的)

#include <bits/stdc++.h>
using namespace std;
const int maxn=110;
const long long mod=1e9+7;
const int inf=1<<30;
typedef long long ll;
double dp[210][210];
//dp[i][j]即为抛了i次后,有j枚硬币正面朝上的概率 
//这里开大点,后面就可以不用判断第二维加上k之后会超100的问题
double p[110];//p数组存放的是1/2的幂次
double c[110][110]; //c数组是求组合数的,别的方法都涉及到取模 
int main()
    c[0][0]=1;
    for(int i=1;i<=100;i++)
    
        c[i][0]=1;
        for(int j=1;j<=i;j++)c[i][j]=c[i-1][j-1]+c[i-1][j];//这个方法求组合数的方法是用到了杨辉三角,高中学的二项式定理 
    
    p[0]=1;
    for(int i=1;i<=100;i++)p[i]=p[i-1]/2;
     int t;cin>>t;
    for(int T=1;T<=t;T++)
        memset(dp,0,sizeof(dp));
        int n,m,t;scanf("%d%d%d",&n,&m,&t);
        dp[0][0]=1;
        for(int i=0;i<m;i++)
            for(int j=0;j<=n;j++)
                if(dp[i][j]==0)continue;//小优化,如果dp[i][j]是0的话,转移来的也都是0,直接不用考虑 
                for(int k=0;k<=t;k++)
                    //反面朝上的硬币数目不大于每次要抛的数目的话,这次就全抛反面朝上的 
                    if(n-j>=t)dp[i+1][j+k]+=dp[i][j]*p[t]*c[t][k];
                    else dp[i+1][j+k-(t-(n-j))]+=dp[i][j]*p[t]*c[t][k];
                    //注意两个都是+= 
                
            
        
        double ans=0;
        for(int i=1;i<=n;i++)
            ans+=dp[m][i]*i;
            //cout<<dp[m][i]<<endl;
        
        printf("%.3lf\n",ans);
    
    return 0;

 

以上是关于概率DP 2017 ICPC 乌鲁木齐 A Coins的主要内容,如果未能解决你的问题,请参考以下文章

2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 H. Skiing (拓扑排序+假dp)

2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 H. Skiing

2017 ICPC Asia Urumqi A.coins (概率DP + 期望)

2017icpc 乌鲁木齐网络赛

2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-A banana·

2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛