题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336
题目大意:有n种卡片,需要吃零食收集,打开零食,出现第i种卡片的概率是p[i],也有可能不出现卡片。问你收集齐n种卡片,吃的期望零食数是多少?
状态压缩:f[mask],代表收集齐了mask,还需要吃的期望零食数。
打开包装,有3种情况,第一种:没有卡片,概率(1-sigma(p[i]))
第二种,在已知种类中:概率sigma(p[j])
第三种,在未知种类中:p[k]
因此 f[mask] = f[mask]*(1-sigma(p[i])) + f[mask] * sigma(p[j]) + sigma(f[mask|k]*p[k]) + 1
1 ///#pragma comment(linker, "/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <cmath> 10 #include <numeric> 11 #include <iterator> 12 #include <iostream> 13 #include <cstdlib> 14 #include <functional> 15 #include <queue> 16 #include <stack> 17 #include <string> 18 #include <cctype> 19 using namespace std; 20 #define PB push_back 21 #define MP make_pair 22 #define SZ size() 23 #define ST begin() 24 #define ED end() 25 #define CLR clear() 26 #define ZERO(x) memset((x),0,sizeof(x)) 27 typedef long long LL; 28 typedef unsigned long long ULL; 29 typedef pair<int,int> PII; 30 const double EPS = 1e-8; 31 32 const int MAX_N = 20; 33 int N; 34 double p[MAX_N+1],f[1<<MAX_N]; 35 36 37 int main(){ 38 39 while( ~scanf("%d",&N) ) { 40 ZERO(f); 41 double sum = 0.0; 42 for(int i=1;i<=N;i++){ 43 scanf("%lf",&p[i]); 44 sum += p[i]; 45 } 46 f[(1<<N)-1] = 0; 47 for( int mask=(1<<N)-2;mask>=0;mask-- ){ 48 double p1 = 0; 49 for(int i=0;i<N;i++){ 50 if( (mask>>i)&1 ) { 51 p1 += p[i+1]; 52 } 53 } 54 // printf("p1 = %f\n",p1); 55 double p2 = 0; 56 for(int i=0;i<N;i++){ 57 if( !((mask>>i)&1) ) { 58 p2 += f[mask|(1<<i)]*p[i+1]; 59 // printf("f[mask|(1<<i)]=%f\n",f[mask|(1<<i)]); 60 } 61 } 62 // printf("p2 = %f\n",p2); 63 f[mask] = (p2+1.0)/(sum-p1); 64 } 65 printf("%.10f\n",f[0]); 66 } 67 68 return 0; 69 }
时间: 2024-10-25 07:33:20