码迷,mamicode.com
首页 > 其他好文 > 详细

2017 ICPC乌鲁木齐 A Coins 概率dp

时间:2019-10-09 00:20:12      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:color   tin   sed   就是   复杂度   ide   printf   图片   硬币   

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\n",ans);
36     }
37     return 0;
38 }
怪怪的哦

 

2017 ICPC乌鲁木齐 A Coins 概率dp

标签:color   tin   sed   就是   复杂度   ide   printf   图片   硬币   

原文地址:https://www.cnblogs.com/LMCC1108/p/11638497.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!