HDU4336:Card Collector

题意

有n张卡片,每一次 有pi的概率买到第i张卡。求买到所有卡的期望购买次数。

n<=20

解析

Solution 1:大力状压(就是步数除以方案数)

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
double a[22],ans;double dp[1<<21];
int T,n;
int main()
{
  while(scanf("%d",&n)!=EOF)
    {
      fp(i,0,n-1) scanf("%lf",&a[i]);
      dp[(1<<n)-1]=0;
      fq(i,(1<<n)-2,0)
	{
	  re double sum=1,x=0;
	  fp(j,0,n-1)
	    {
	      if(!(i&(1<<j)))
		{
		  x+=a[j];
		  sum+=dp[i|(1<<j)]*a[j];
	        }
	      dp[i]=sum/x;
	    }
	}
	printf("%.4lf
",dp[0]);
    }
  return 0;
}

Solution 2:min_max容斥

不知道有什么用。。。。

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
double a[22],ans;//double dp[1<<21];
int T,n;
il void dfs(re int x,re double s,re int f)
{
  if(x>n) {if(s>1e-9) ans+=f*1/s;return;}
  dfs(x+1,s+a[x],-f);dfs(x+1,s,f);
}
int main()
{
  while(scanf("%d",&n)!=EOF)
    {
      fp(i,1,n) scanf("%lf",&a[i]); 
      ans=0;dfs(1,0,-1);
      printf("%.4lf
",ans);
    }
  return 0;
}
原文地址:https://www.cnblogs.com/yanshannan/p/8670606.html