题意:
给出n种不同卡片在买的小吃力里面出现的可能,求凑齐n种卡片要买的小吃的平均数量。
思路:
根据官方解题报告做的:
设卡片的分布p=(p1,p2,...,pn),T(p)表示拿到所有卡片时买的零食数目,有
由容斥原理得,
代码(1)这个是我比赛时胡乱写的一个程序,竟然过了,可见数据是如此的弱!!!!
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n;
double p[20],sum,ans;
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF)
{
sum=0;
for(i=1;i<=n;i++)
{
scanf("%lf",&p[i]);
sum+=p[i];
}
if(n==1)
{
printf("%.3lf\n",1.0/p[1]);
}
else
{
for(i=1;i<=n;i++)
{
ans+=1.0/p[i];
}
printf("%.3lf\n",ans-1.0/sum);
}
}
return 0;
}
代码(2)是我的好友 E_Star 写的一个程序 拿出来晒晒 :、
#include <cstdio>
#include <iostream>
using namespace std;
const int maxn = 22;
double p[maxn];
int main() {
int n,i,j;
while (~scanf("%d",&n))
{
for (i = 0; i < n; ++i) scanf("%lf",&p[i]);
double ans = 0.0;
//根据二项式定理C(n,0)+C(n,1) + ... + C(n,n) = 2^n
//所以这里2^n - 1种可能,枚举
for (i = 1; i < (1<<n); ++i)
{
int ct = 0;
double tmp = 0.0;
for (j = 0; j < n; ++j)
{
if (i&(1<<j))//检查0到n中存在于i状态的点
{
ct++;
tmp += p[j];
}
}
//鸽巢定理
if (ct&1) ans += 1.0/tmp;
else ans -= 1.0/tmp;
}
printf("%.4lf\n",ans);
}
return 0;
}