YBTOJ:彩球抽取(期望)

题目描述

请添加图片描述

解析

首先,可以使用dp解决本题
设fi,j,k:操作i轮之后编号j的小球有k个的概率
转移和统计答案就都不难了
但是还有一个问题
不难发现这个题循环下去是可以无穷无尽的
所以限定一个i的上界(如500000),在损失精度可以接受的前提下使答案可求

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e7+100;
const int mod=20040313;
int n,num[28],id[28],tot;
char s[28];
double dp[2][28][28];
int main(){
	scanf("%s",s+1);
	tot=strlen(s+1);
	for(int i=1;i<=tot;i++){
		int now=s[i]-'A'+1;
		if(id[now]==0) id[now]=++n;
		num[id[now]]++;
		//printf("s=%c id=%d num=%d\n",s[i],id[now],num[id[now]]);
	}
	for(int i=1;i<=n;i++){
		//printf("i=%d num=%d\n",i,num[i]);
		dp[1][i][num[i]]=1.0;
	}
	int now=1;
	double ans=0;
	for(int k=0;k<=50000;k++){
		for(int i=1;i<=n;i++) ans+=dp[now][i][tot]*k;
		now^=1;int pre=now^1;
		for(int i=1;i<=n;i++){
			for(int j=0;j<=tot;j++) dp[now][i][j]=0;
		}
		//printf("k=%d now=%d pre=%d\n",k,now,pre);
		for(int i=1;i<=n;i++){
			for(int j=0;j<tot;j++){
				double p=1.0*j*(tot-j)/(tot*(tot-1));
				//printf("  col=%d num=%d dp=%lf p=%lf\n",i,j,dp[pre][i][j],p);
				if(j>0) dp[now][i][j-1]+=dp[pre][i][j]*p;
				dp[now][i][j+1]+=dp[pre][i][j]*p;
				dp[now][i][j]+=dp[pre][i][j]*(1.0-2*p);
			}
		}
		//printf("k=%d ans=%lf\n",k,ans);
	}
	printf("%.6lf\n",ans);
	return 0;
}
/*


*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值