Codeforces Round #333 (Div. 1) C

来源:互联网 发布:c语言乘法口诀 编辑:程序博客网 时间:2024/04/27 07:06

Kleofáš and the n-thlon

        概率dp。dp求的东西是除了自己以外,其他人得到各种分数的概率,状态转移见代码。然后就可以算出其他人超过自己的概率了。根据这个概率,结合组合数,计算期望。由于精度问题,要先取对数。还要注意概率为0,1的情况。


#include <bits/stdc++.h>using namespace std;#define ll long longdouble dp[2][100010];int a[110];int main(){int n,m;//比赛 人 cin>>n>>m;int sum=0;for(int i=1;i<=n;i++){cin>>a[i];sum+=a[i];}dp[0][0]=1;int MAX;for(int i=1;i<=n;i++){MAX=m*i;for(int j=0;j<=MAX;j++){dp[i&1][j]=0;}double tmp=0;for(int j=0;j<=MAX;j++){tmp+=dp[(i-1)&1][j-1];if(j>m){tmp-=dp[(i-1)&1][j-m-1];}dp[i&1][j]+=tmp;if(j>=a[i])dp[i&1][j]-=dp[(i-1)&1][j-a[i]];}}double smaller=0;double total=0;if(m==1){cout<<1<<endl;return 0;}for(int i=1;i<=MAX;i++){if(i<sum){smaller += dp[n&1][i];}total += dp[n&1][i];}double p = smaller/total;if(p==0){cout<<1<<endl;return 0;}else if(p==1){cout<<m<<endl;return 0;}double curP = log2(1-p)*(m-1);double ans = 0;double C = 0;for(int i=1;i<=m;i++){ans+=pow(2,curP+C+log2(i));curP+=log2(p);curP-=log2(1-p);C+=log2(m-i);C-=log2(i);}printf("%.10f\n",ans);return 0;}


0 0