其他分享
首页 > 其他分享> > 『期望DP』POJ2096:Collecting Bugs

『期望DP』POJ2096:Collecting Bugs

作者:互联网

题目描述

题意:s个系统n种bug,每天找出一个bug,种类的概率是1/n,系统的概率是1/s。问:每个系统至少找出一个bug;每种类的bug都被找出。的期望天数(0<n, s<=1000)、

题解

这道题目一共有两个维度,bug个系统,这了对应了两个状态。

我们设f[i][j]f[i][j]f[i][j]为i个bug,s个系统,还需要期望的步数。我们要采用逆推。(逆推的原因就在于状态0也在考虑范围内,往前访问会造成下标越界)。

一共分为如下情况:

可以很容易得到状态转移方程:
f[i][j]=f[i][j+1]×i×(sj)s×n+f[i+1][j]×(ni)×js×n+f[i+1][j+1]×(ni)×(sj)s×n+f[i][j]×i×js×n+1f[i][j]=f[i][j+1]\times \frac{i\times (s-j)}{s\times n}+f[i+1][j]\times \frac{(n-i)\times j}{s\times n}\\+f[i+1][j+1]\times \frac{(n-i)\times (s-j)}{s\times n}+f[i][j]\times \frac{i\times j}{s\times n}+1f[i][j]=f[i][j+1]×s×ni×(s−j)​+f[i+1][j]×s×n(n−i)×j​+f[i+1][j+1]×s×n(n−i)×(s−j)​+f[i][j]×s×ni×j​+1

然后移项一下就可以辣~

#include <iostream>
#include <cstdio>

using namespace std;

int n, s;
double f[3000][3000];

int main(void)
{
	cin>>n>>s;
	f[n][s] = 0;
	for (int i=n;i>=0;--i)
	    for (int j=s;j>=0;--j) 
			if (i != n || j != s) {
	    	double val1 = 1.0 * f[i+1][j] * (n-i) * j / s / n;
	    	double val2 = 1.0 * f[i][j+1] * i * (s-j) / s / n;
	    	double val3 = 1.0 * f[i+1][j+1] * (n-i) * (s-j) / s / n;
	    	double val4 = 1.0 - 1.0 * i * j / s / n;
	    	f[i][j] = 1.0*(val1+val2+val3+1)/val4;
	    }
	printf("%.4f\n", f[0][0]); 
	return 0;
}

标签:Collecting,POJ2096,frac,int,double,Bugs,times,1.0,bug
来源: https://blog.csdn.net/Ronaldo7_ZYB/article/details/99108185