[HDU 4336]Card Collection[状态压缩DP][概率DP][容斥原理]
来源:互联网 发布:期货数据库 编辑:程序博客网 时间:2024/05/29 17:24
题意:
小吃中有N种卡片,每种卡片 i 出现的概率为 pi ,一袋小吃有可能没有卡片,但最多有一张.问集齐所有卡片需要购买小吃的袋数期望.
思路:
1.用状压dp,dp[ s ]表示在s状态时,集齐所需要的袋数期望.
s = 11111表示N = 5时集齐的状态,此时dp[ s ] = 0;
注意求期望的题,对于dp的定义一般都是从终态转移到初态,也就是反着求.
因为"期望"是
确定事件的结果 * 该事件发生的概率 = 平均来看尝试一次可以得到的结果,即期望
若是在s1状态得到一张卡片转移到了s2,那么s2是一个确定的状态,而在s1时则有多种可能性.由此可以理解反着求的合理性.
终态是初态的"去向",确是期望的"来源".
//281MS8480K#include<cstdio>using namespace std;const int MAXN=22;double p[MAXN];double dp[1<<MAXN];int main(){ int n; while(scanf("%d",&n)!=EOF) { double tt=0; for(int i=0;i<n;i++) { scanf("%lf",&p[i]); tt+=p[i]; } tt=1-tt;//tt就表示没有卡片的概率了 dp[(1<<n)-1]=0;//全部收集到了就不需要再买了.求期望一般都是反着推. for(int i=(1<<n)-2;i>=0;i--)//遍历所有方案 { double x=0,sum=1;///肯定要拿自己那一张卡片 for(int j=0;j<n;j++) { if((i&(1<<j)))x+=p[j];///如果此种卡片在i中已经存在,累加其概率 else sum+=p[j]*dp[i|(1<<j)];///若不存在,说明可以由此种情况转化而来///dp[i|(1<<j)]是"确定事件",p[j]是该确定事件发生的概率,相乘则表示期望. } dp[i]=sum/(1-tt-x); } printf("%.5lf\n",dp[0]); } return 0;}自己敲一遍:
//250MS 8480K#include<cstdio>using namespace std;const int MAXN = 22;double p[MAXN],dp[1<<MAXN];int main(){ int N,m; while(scanf("%d",&N)==1) { for(int i=0;i<N;i++) scanf("%lf",p+i); m = 1 << N ; dp[m-1] = 0; for(int i=m-2;i>=0;i--) { double sump = 0,sum = 1; for(int j=0;j<N;j++) { if(!(i & (1<<j)))//位运算写成了逻辑与...手残 { sump += p[j];//有用的概率 sum += p[j]*dp[i|(1<<j)]; } } dp[i] = sum / sump; } printf("%.5lf\n",dp[0]);///虽然样例中输出是保留了3位,但是题中描述是误差1e-4的...所以... }}2.容斥原理(先记下,稍后学习...)
//421MS340K#include<iostream>#include<cstdio>using namespace std;double s; int n,vis[25];double a[25];void dfs(int k,double sum,int cou,int j){ if(cou==k){ s+=1/sum; return ; } for(int i=j;i<=n;i++){ sum+=a[i]; cou++; dfs(k,sum,cou,i+1); cou--; sum-=a[i]; } return ;}int main(){ while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ scanf("%lf",&a[i]); } double sum=0; for(int i=1;i<=n;i++) sum+=(1/a[i]); for(int i=2;i<=n;i++){ s=0; dfs(i,0,0,1); if(i%2==0) sum+=(-1)*s; else sum+=s; } printf("%lf\n",sum); }}/*HDU 4336容斥原理位元素枚举*/#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;double p[22];int main(){ int n; while(scanf("%d",&n)==1) { for(int i=0;i<n;i++)scanf("%lf",&p[i]); double ans=0; for(int i=1;i<(1<<n);i++) { int cnt=0; double sum=0; for(int j=0;j<n;j++) if(i&(1<<j)) { sum+=p[j]; cnt++; } if(cnt&1)ans+=1.0/sum; else ans-=1.0/sum; } printf("%.5lf\n",ans); } return 0;}
- [HDU 4336]Card Collection[状态压缩DP][概率DP][容斥原理]
- HDU 4336 Card Collector 概率dp 状态压缩| 容斥原理
- hdu 4336 Card Collector(概率dp, 容斥原理)
- HDU 4336 Card Collector (容斥原理||概率DP)
- Hdu 4336 Card Collector (状态概率DP|容斥原理)
- hdu 4336 Card Collector 概率DP 状态压缩DP
- HDU 4336 Card Collector(状态压缩dp+概率dp)
- HDU 4336 Card Collector 状态压缩+概率DP
- hdu 4336 Card Collector 概率dp+状态压缩
- HDU 4336 Card Collector 状态压缩 概率DP
- hdu 4336 Card Collector(状态压缩概率dp)
- HDU 4336Card Collector 概率dp 状态压缩
- HDU 4336 Card Collector(状态压缩+概率DP)
- Hdu 4336 Card Collector 概率DP+状态压缩
- hdu - 4336 - Card Collector - 容斥 || 概率dp
- hdu 4336 Card Collector(概率DP 或 容斥原理)
- HDU 4336 Card Collector (概率DP 或 容斥原理)
- HDU-4336 Card Collector(状压概率DP||容斥原理)
- PhysicsEditor的应用
- C++获取系统图标方法
- 后缀自动机学习资料
- 跟我一起学Python之九:字符串常用方法
- java 打印表格文件
- [HDU 4336]Card Collection[状态压缩DP][概率DP][容斥原理]
- HDU 4666 Hyperspace
- WinXP硬盘安装Ubuntu 11.10双系统全程图解
- Java主类结构
- Power Strings(poj2406 ,简单KMP)
- dsPIC33F之Latched Fault Code Workaround via PWM Override Logic Routine
- 两个ViewController间传值(二)
- 生成IPA文件
- HDOJ 1158