2017 ICPC乌鲁木齐 A Coins 概率dp

Posted lmcc1108

tags:

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

Coins

题意:一开始所有n个硬币都是反面朝上的,每次必须拿k个来抛,抛的人足够聪明,问m次之后向上的硬币的期望。

首先说了这个足够聪明的意思,就是只要向反面的有k个就不会sb地去拿向正面的来抛,想了一会之后就觉得是个概率dp的转移,

然而一开始想漏了个组合数的加权,但在+1的提醒下搞通了,但是分析了下,这是nmk的时间复杂度,

1e6还有个1e3的大T,emmm理论上会TLE的,但结果看网上题解,都是跟自己思路差不多,所以也是很迷。

嗯,转移过程其实很简单,dp[i][j]就是第i次抛了之后j个硬币向上的概率,所以如果n-j>=k很明显,这是全部拿向反面的来抛就行,那么dp[i+1][j+kk]=dp[i][j]*0.5的k次方*k个里面有kk个向正面的组合数

而n-j<的话,那么就得那一些向正面的来抛了,剩下的正面的就j-(k-(n-j))也就是n-k个,那么dp[i+1][n-k+kk]=dp[i][j]*0.5的k次方*k个里面有kk个向正面的组合数

技术图片
 1 #include<cstdio>
 2 const int N=111;
 3 double cf05[N],c[N][N],dp[N][N];
 4 void init(){
 5     for(int i=0;i<=100;i++){
 6         c[i][0]=1.0;
 7         for(int j=1;j<=i;j++){
 8             if(j<=i/2) c[i][j]=c[i-1][j-1]+c[i-1][j];
 9             else c[i][j]=c[i][i-j];
10         }
11     }
12     cf05[0]=1.0;
13     for(int i=1;i<=100;i++) cf05[i]=cf05[i-1]*0.5;
14 }
15 int main(){
16     init();
17     int t,n,m,k;
18     scanf("%d",&t);
19     while(t--){
20         scanf("%d%d%d",&n,&m,&k);
21         for(int i=0;i<=m;i++)
22             for(int j=0;j<=n;j++) dp[i][j]=0.0;
23         dp[0][0]=1.0;
24         for(int i=0;i<m;i++){
25             for(int j=0;j<=n;j++){
26                 if(dp[i][j]==0.0) continue;
27                 for(int kk=0;kk<=k;kk++){
28                     if(n-j>=k) dp[i+1][j+kk]+=dp[i][j]*cf05[k]*c[k][kk];
29                     else dp[i+1][n-k+kk]+=dp[i][j]*cf05[k]*c[k][kk];
30                 }
31             }
32         }
33         double ans=0.0;
34         for(int i=0;i<=n;i++) ans+=dp[m][i]*i;
35         printf("%.3f
",ans);
36     }
37     return 0;
38 }
怪怪的哦

 

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

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

欧拉公式 大组合数 2017 ICPC 乌鲁木齐 D Fence Building

2017icpc 乌鲁木齐网络赛

ACM-ICPC 2017 Asia Urumqi A. Coins期望dp

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

ACM-ICPC 2017 Asia Urumqi:A. Coins(DP)