『期望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也在考虑范围内,往前访问会造成下标越界)。

一共分为如下情况:

  • bug不出现,系统出现。对应了f[i][j+1],p=i×(sj)s×nf[i][j+1],p=\frac{i\times (s-j)}{s\times n}f[i][j+1],p=s×ni×(s−j)​
  • bug出现,系统不出现。对应了f[i+1][j],p=(ni)×js×nf[i+1][j],p=\frac{(n-i)\times j}{s\times n}f[i+1][j],p=s×n(n−i)×j​
  • bug出现,系统出现。对应了f[i+1][j+1],p=(ni)×(sj)s×nf[i+1][j+1],p=\frac{(n-i)\times (s-j)}{s\times n}f[i+1][j+1],p=s×n(n−i)×(s−j)​
  • bug不出现,系统不出现。对应了f[i][j],p=i×js×nf[i][j],p=\frac{i\times j}{s\times n}f[i][j],p=s×ni×j​

可以很容易得到状态转移方程:
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;
}
上一篇:AIApe问答机器人Scrum Meeting 5.5&5.6


下一篇:处理bugs心法