首先压缩状态,表示当前已经收集到的卡片和没收集到的卡片
然后是求取公式:
取随机变量:到达凑齐状态,需要抽取的卡片数
E[i]表示当前状态i到目标状态,需要抽取卡片的期望
假设state为凑齐的状态
E[state] = 0;
p1表示抽到的卡片已经被抽取过或没抽到卡片的概率
E[i] = (E[i]+1)*p1+(E[j]+1)*p[j比i唯一少取的卡片]
-> E[i] = ( p1 + (E[j]+1)*p[......] )/(1-p1)
然后最后结果就是E[0]...
在概率dp中属于比较经典也比较水的..........
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define MAX 22
using namespace std;
int n;
double p[MAX];
double dp[1<<(MAX-1)];
int main ( )
{
while ( ~scanf ( "%d" , &n ) )
{
memset ( dp , 0 , sizeof ( dp ) );
double temp = 1.0;
for ( int i = 0 ; i < n ; i++ )
{
scanf ( "%lf" , &p[i] );
temp -= p[i];
}
int total = (1<<n)-1;
for ( int i = total-1 ; i >= 0 ; i-- )
{
double pp = temp;
for ( int j = 0 ; j < n ; j++ )
{
if ( !(i&(1<<j)))
dp[i] += ( dp[i^(1<<j)] + 1 ) * p[j];
else pp += p[j];
}
dp[i] += pp;
dp[i] /= ( 1 - pp );
}
printf ( "%.5lf\n" , dp[0] );
}
}