HDU 4336 Card Collector
来源:互联网 发布:怎么加入淘宝灯具安装 编辑:程序博客网 时间:2024/06/06 08:31
题意:一种儿童食品,每包这种食品中可能会有一张卡片,且卡片一共有N种,而且每种卡片出现在一包这种食品中的概率不同,分别为p1,p2...pn。问集齐这N种卡片要买的食品的期望数量是多少。
分析:概率DP+状态压缩。因为每种卡片出现在一包中的概率不是相等的,所以当计算集齐i种卡片时,要知道是那些已经收集到而哪些没有收集到,所以可以用状态压缩DP来解决。
设dp[s]为收集卡片种类集合为s的期望,则有:
dp[s]=(1-sigma(p[i]))*dp[s]+sigma(p[j]*dp[s])+sigma(dp[s|(1<<k)]*p[k])+1(i指买到的食品中没有卡片,j指买到的食品中的卡片是已近收集到的,k指买到的食品中收集到的卡片是一种新的没有收集到的卡片)。
移项化简可得:
dp[s]={sigma(dp[s|(1<<k)]*p[k])+1}/sigma(p[k])。
Code:
#include <algorithm>#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <vector>#include <queue>#include <cmath>#include <map>#include <set>#define eps 1e-7#define LL long long#define pb push_back#define Max(a,b) ((a)>(b)?(a):(b))#define Min(a,b) ((a)<(b)?(a):(b))using namespace std;const int maxn=20;double p[maxn+5],dp[1<<maxn];int n;int main(){ while(scanf("%d",&n)==1){ for(int i=0;i<n;i++) { scanf("%lf",&p[i]); } dp[(1<<n)-1]=0.0; for(int s=(1<<n)-2;s>=0;s--){ dp[s]=1.0; double pk=0.0; for(int k=0;k<n;k++){ if(s&(1<<k)) continue; dp[s]+=dp[s|(1<<k)]*p[k]; pk+=p[k]; } dp[s]/=pk; } printf("%lf\n",dp[0]); } return 0;}
- HDU 4336 - Card Collector
- hdu 4336 Card Collector
- hdu 4336 Card Collector
- HDU 4336 Card Collector
- hdu 4336 Card Collector
- hdu 4336 Card Collector
- hdu 4336 Card Collector
- HDU 4336 Card Collector
- HDU 4336 Card Collector
- HDU 4336 Card Collector
- hdu 4336 Card Collector
- hdu 4336 Card Collector(期望)
- hdu 4336 Card Collector[期望]
- hdu 4336 Card Collector (容斥原理)
- hdu 4336 Card Collector(概率DP)
- 期望dp-hdu-4336-Card Collector
- hdu 4336 Card Collector (概率dp)
- [容斥]HDU 4336 Card Collector
- 使用xsd.exe生成C#类
- 最多连续数的子集
- iOS深浅拷贝
- java中的冒泡排序法
- activiti5.13 globalTaskListener 实现
- HDU 4336 Card Collector
- Java IDE 之Eclipse
- MYSQL:将所有表的存储引擎格式进行修改
- HDU4556(递推求欧拉函数)
- 第一门编程语言选谁
- POJ2480(欧拉函数求最大公约数之和)
- 数据库时间格式转化
- 指针,引用,取值
- 系统问题导致的笔记本部分按键失灵