You will get accepted if the difference between your answer and the standard answer is no more that 10^-4.
Sample Input 1 0.1 2
0.1 0.4
Sample Output 10.000
10.500
题意:N种卡,给出每种卡抽中的概率。每包零食里可能有一种卡,也可能没有。求集齐所有卡片需要买零食数的期望。
思路:
1.dp[i]表示当前拥有的卡的状态为i,要集齐所有卡片的次数的期望。
2.初始状态是,如果我拥有所有的卡,则需要0次购买零食。因此dp[1<<n-1]=0,要求的是dp[0]。
3.先得到零食里没有卡片的概率pp。对于i状态,没有卡片的次数期望为(dp[i]+1)*pp。枚举卡片j,如果已有这张卡,次数的期望是(dp[i]+1)*p[j];没有这张卡,次数的期望为(dp[i|1<<j]+1)*p[j]。三种情况的和等于dp[i]。列方程解出dp[i]。
#include <cstring> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <algorithm> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> using namespace std; double p[30]; double dp[1<<22]; int main() { int n; while(scanf("%d",&n)!=EOF) { double pp=1.0; for(int i=0;i<n;i++) { scanf("%lf",&p[i]); pp-=p[i]; } dp[(1<<n)-1]=0; for(int i=(1<<n)-2;i>=0;i--) { double sum=0; double x=0; for(int j=0;j<n;j++) { if(i&(1<<j)) x+=p[j]; else sum+=p[j]*(dp[i|(1<<j)]+1); } dp[i]=(sum+pp+x)/(1-pp-x); //dp[i]=(pp+x)*(dp[i]+1)+sum } printf("%.5lf\n",dp[0]); } return 0; }