HDU 4336 (概率DP+状压)

题意:买泡面,得水浒传n张英雄卡,每张卡有一个得到的概率,问购买次数的期望,能集齐所有卡


思路:概率dp+状态压缩,dp[s]表示搜集到的卡片状态的期望次数,1表示有的,0表示没有,那么dp[s] = (1 - sum(p[i])) * dp[s] + p[k] * dp[s] + p[j] * dp[s|(1<<j)] + 1,其中i为所有英雄,k为已经搜集到的英雄,j为还未搜集到的英雄,移项得,dp[s] = (sum(p[j] * dp[s|(1<<j)]) + 1) / sum[p[j]];

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 25;

int n;
double p[N], dp[(1<<20) + 5];

int main() {
	while (~scanf("%d", &n)) {
		for (int i = 0; i < n; i++) scanf("%lf", &p[i]);
		int maxs = (1<<n) - 1;
		for (int i = maxs - 1; i >= 0; i--) {
			dp[i] = 1;
			double sum = 0;
   			for (int j = 0; j < n; j++) {
   				if (!(i&(1<<j))) {
   					dp[i] += p[j] * (dp[i|(1<<j)]);
   					sum += p[j];
       			}
   			}
   			dp[i] /= sum;
  		}
  		printf("%.4lf\n", dp[0]);
 	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值