题解说是容斥原理,彻底没看懂,搜到的题解也是各种简洁,就提到是容斥原理,难道大家的数学都这么好,一眼就看懂了。。。。
这题也可以用概率DP做,相比之下这种做法要容易理解的多。用一个状态表示当前抽到的卡片的状况,1代表尚未拿的卡片,有d[now]=x*d[now]+sigma(si*pi*(now^(1<<i)))+1,si表示stat中该位是0还是1,x表示停留在该状态的概率,即没拿到其它卡片的概率(没抽到卡片+抽到当前已有卡片),移项可以得到d[now]=sigma(..)/(1-x)。
1 #include <string.h> 2 #include <stdio.h> 3 int n; 4 double p[25],d[1<<21]; 5 //d[stat] stat中为1的位表示尚未拿的卡片 6 //d[now]=x*d[now]+sigma(si*pi*(now^(1<<i)))+1,si表示stat中该位是0还是1 7 //移项有d[now]=sigma(..)/(1-x) x表示停留在该状态的概率,即没拿到其它卡片 8 int main(){ 9 while(scanf("%d",&n)!=EOF){ 10 double tot=0; 11 for(int i=0;i<n;i++){ 12 scanf("%lf",&p[i]); 13 tot+=p[i]; 14 } 15 tot=1-tot,d[0]=0; 16 for(int i=1;i<(1<<n);i++){ 17 double x=0,sigma=1; 18 for(int j=0;j<n;j++){ 19 if(((i>>j)&1)==0)x+=p[j]; 20 else sigma+=p[j]*d[i^(1<<j)]; 21 } 22 d[i]=sigma/(1-tot-x); 23 } 24 printf("%.5f\n",d[(1<<n)-1]); 25 } 26 return 0; 27 }