码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4336 Card Collector(概率DP)

时间:2015-07-31 20:22:44      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:hdu



题意:有n种卡片,吃零食的时候会吃到一些卡片,告诉你在一袋零食中吃到每种卡片的概率,求搜集齐每种卡片所需要买零食的袋数的期望。

思路:先状态压缩,然后概率DP

用d[i]表示由状态i到目标需要再买多少包,则状态转移方程为d[i] = p‘*(d[i]+1) + sigma(d[ i | (1 << j) * p[i] ),然后相同项移到左边,最后就可以得到答案。

#include<cstdio>  
#include<cstring>  
#include<cmath>  
#include<cstdlib>  
#include<iostream>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<queue>  
#include<stack> 
#include<string>
#include<map> 
#include<set>
#define eps 1e-6 
#define LL long long  
#define pii pair<int,int>
using namespace std;  

//const int maxn = 100 + 5;
//const int INF = 0x3f3f3f3f;
//freopen("input.txt", "r", stdin);
double p[25];
double d[1<<21];

int main() {
	int n;
	while(scanf("%d", &n) == 1) {
		double no = 1; 
		for(int i = 0; i < n; i++) {
			scanf("%lf", &p[i]);
			no -= p[i];
		}
		int s = (1 << n)-1;
		d[s] = 0;
		for(int i = s-1; i >= 0; i--) {
			double tp = no;
			d[i] = no;
			for(int j = 0; j < n; j++) {
				if((1<<j)&i) {
					tp += p[j];
					d[i] += p[j];
				}
				else d[i] += p[j]*(d[i|(1<<j)]+1);
			}
			d[i] = d[i]/(1-tp);
		}
		printf("%.6lf\n", d[0]);
	}
	return 0;
}





版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 4336 Card Collector(概率DP)

标签:hdu

原文地址:http://blog.csdn.net/u014664226/article/details/47174527

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!