这题说实话我也没咋看懂,只是把我的一些想法贴注释里吧,不要当真,也许全想错了(话说来个大牛告诉sum到底是什么意思啊啊啊啊)
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
const int MAXN=21;
double p[MAXN];
double dp[1<<MAXN];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i,j;
double t=0;
for(i=0;i<n;i++)
{
scanf("%lf",&p[i]);
t+=p[i];
}
t=1-t; //t就表示没有卡片的概率了
dp[(1<<n)-1]=0; //全部收集到了就不需要再买了.求期望一般都是反着推.
for(i=(1<<n)-2;i>=0;i--)
{
double sum=1,pp=0;
for(j=0;j<n;j++)
{
if(i&(1<<j))
pp+=p[j];
else
sum+=p[j]*dp[i|(1<<j)]; //sum表示期望值,加上去的表示通过那种取法还差多少才能达到dp[i|(1<<j)]的要求
}
dp[i]=sum/(1-t-pp); //dp[i]*p是期望值
}
printf("%.5lf\n",dp[0]);
}
return 0;
}