POJ 2096 Collecting Bugs 概率DP(期望)

点击打开链接

题意:n种病毒,s个系统 每次能在某个系统下发现某个病毒,求发现n种病毒&&每个系统至少发现一个病毒所需要的期望次数? 


令d[i][j]表示当前发现了i种病毒&&发现j个系统中至少有一个病毒时,离目标(n,s)所需要的期望次数

然后根据E(aA+bB+cC+dD+...)=aEA+bEB+....;//a,b,c,d...表示概率,A,B,C...表示状态  

每次有4种情况 

已发现系统找到同一种病毒,概率为:p1=(i/n)*(j/s) 
没发现系统中找到同一种病毒,p2=(i/n)*((s-j)/s)
已发现系统中找到不同种病毒 p3=((n-i)/n)*(j/s)
没发现系统中找到不同种病毒 p4=((n-i/n))*((s-j)/s)


d[i][j]=1+p1*d[i][j]+p2*dp[i][j+1]+p3*dp[i+1][j]+p4*dp[i+1][j+1]
d[i][j]移项: d[i][j]=(1+p2*dp[i][j+1]+p3*dp[i+1][j]+p4*dp[i+1][j+1])/(1-p1)

#include <iostream>
#include <cstdio>
#include <cstring> 
using namespace std;
typedef long long ll;
const ll inf=1e15;
const int N=2e3+50;
int n,s;
double dp[N][N];
int main()
{
	while(cin>>n>>s)
	{
		
		
		memset(dp,0,sizeof(dp));
		for(int i=n;i>=0;i--)
		{
			for(int j=s;j>=0;j--)
			{
				if(i==n&&j==s) continue;
				double p=1.0-(double)(i*j)/(n*s);
				dp[i][j] += (double) (n - i) * (s - j) / (n * s) * dp[i+1][j+1];
                dp[i][j] += (double) i * (s-j) / (n * s) * dp[i][j+1];
                dp[i][j] += (double) (n - i) * j / (n * s) * dp[i+1][j];
                dp[i][j]=(dp[i][j]+1.0)/p;
			}
		}
		printf("%.4lf\n",dp[0][0]);
	}
	
	

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值