Kids and Prizes(概率+期望)

http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=113#problem/K


概率又还给老师了。。。

有n个奖品放在n个盒子里,有m个小朋友轮流去选择一个盒子,若有奖品则拿走,无论有没有奖品都要将空盒子放回去。问最后获得奖品的期望。


只要求出每个小朋友获得奖品的概率,期望就是这些概率的和。设dp[i]表示第i个小朋友获得奖品的概率,得到dp[i]的地推方程:

dp[i] = (1 - dp[i-1]) * dp[i-1] + dp[i-1] * (dp[i-1] - 1/n)。(1 - dp[i-1]) * dp[i]表示第i-1个小朋友没拿到奖品,第i个小朋友拿到奖品的概率,dp[i-1] * (dp[i-1] - 1/n)表示第i-1个小朋友拿到奖品且第i个小朋友拿到奖品的概率,因为第i-1个小朋友拿到了奖品,所以第i个小朋友拿到奖品的概率为dp[i-1]-1/n,即它拿到奖品的概率减小了1/n。这里的递推没有想到。


#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
//#define LL __int64
#define LL long long
#define eps 1e-8
#define PI acos(-1.0)
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 100010;

int n,m;
double dp[maxn];

int main()
{
	while(~scanf("%d %d",&n,&m))
	{
		memset(dp,0,sizeof(dp));
		dp[1] = 1.0;
		for(int i = 2; i <= m; i++)
		{
			dp[i] = (1-dp[i-1])*dp[i-1] + dp[i-1] * (dp[i-1]-1.0/n);
		}
		double ans = 0;
		for(int i = 1; i <= m; i++)
			ans += dp[i];
		printf("%.10lf\n",ans);
	}
	return 0;
}





你可能感兴趣的:(概率DP)