HDU 4336 Card Collector [状态压缩概率DP]

  题解说是容斥原理,彻底没看懂,搜到的题解也是各种简洁,就提到是容斥原理,难道大家的数学都这么好,一眼就看懂了。。。。

  这题也可以用概率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 }
原文地址:https://www.cnblogs.com/swm8023/p/2661269.html