标签:limits rac for har stdio.h sum highlight length mit
题意:有$k$种苹果和$n$个箱子,每个箱子中有一些苹果,先等概率选取$n$个箱子组成集合的非空子集,再从选出的苹果中随机选一个,问每种苹果被选中的概率是多少
设箱子$i$有$cnt_{i,j}$个第$j$种苹果,第$i$个箱子的总苹果数$siz_i=\sum\limits_{j=1}^kcnt_{i,j}$,苹果总数$sum=\sum\limits_{i=1}^nsiz_i$
因为选完非空子集后,每个箱子中的苹果被选中的概率是相同的,所以先考虑选箱子,设$f_{i,j}$表示在前$i$个箱子中选$j$个苹果的方案数(只能一箱一箱选),那么$f_{i,j}=f_{i-1,j}+f_{i-1,j-siz_i}$
再设$g_{i,j}$表示在所有不是$i$的箱子中选$j$个苹果的方案数,那么$g_{i,j}=f_{n,j}-g_{i,j-siz_i}$
于是,选中了箱子$i$的情况对箱子$i$中每个苹果被选中的概率贡献为$\frac1{2^n-1}\sum\limits_{j=0}^{sum-siz_i}\frac{g_{i,j}}{j+siz_i}$(枚举箱子$i$外被选中的苹果数)
#include<stdio.h> #include<vector> #include<string> #include<string.h> using namespace std; typedef double du; typedef long long ll; ll f[500010],g[500010]; int cnt[60][60],siz[60],sum; class RandomApple{ public: vector<du>theProbability(vector<string>hun,vector<string>ten,vector<string>one){ int n,k,i,j; du t; n=hun.size(); k=hun[0].length(); for(i=0;i<n;i++){ for(j=0;j<k;j++){ cnt[i][j]=(hun[i][j]-‘0‘)*100+(ten[i][j]-‘0‘)*10+one[i][j]-‘0‘; siz[i]+=cnt[i][j]; } sum+=siz[i]; } vector<du>res(k,0); f[0]=1; for(i=0;i<n;i++){ for(j=sum;j>=siz[i];j--)f[j]+=f[j-siz[i]]; } for(i=0;i<n;i++){ memset(g,0,sizeof(g)); t=0; for(j=0;j<=sum;j++){ g[j]=f[j]-(j>=siz[i]?g[j-siz[i]]:0); if(j+siz[i]<=sum)t+=g[j]/(du)((1ll<<n)-1)/(du)(j+siz[i]); } for(j=0;j<k;j++)res[j]+=t*cnt[i][j]; } return res; } }; /* int main(){ RandomApple cl; vector<string>a,b,c; vector<du>res; char s[60]; for(scanf("%s",s);s[0]!=‘-‘;scanf("%s",s))a.push_back(s); for(scanf("%s",s);s[0]!=‘-‘;scanf("%s",s))b.push_back(s); for(scanf("%s",s);s[0]!=‘-‘;scanf("%s",s))c.push_back(s); res=cl.theProbability(a,b,c); for(du t:res)printf("%.9lf ",t); } */
标签:limits rac for har stdio.h sum highlight length mit
原文地址:https://www.cnblogs.com/jefflyy/p/9583530.html