Codeforces Round #333 (Div. 1) C

Kleofáš and the n-thlon

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


#include <bits/stdc++.h>
using namespace std;

#define ll long long

double 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值