POJ 2096Collecting Bugs 概率期望dp
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2096Collecting Bugs 概率期望dp相关的知识,希望对你有一定的参考价值。
题意
有s个系统,n种bug,小明每天找出一个bug,可能是任意一个系统的,可能是任意一种bug,即是某一系统的bug概率是1/s,是某一种bug概率是1/n。
求他找到s个系统的bug,n种bug,需要的天数的期望。
分析
计算期望E=∑所有可能需要的天数*概率
找到s个系统n种bug,需要最少max(s,n)天,而可能的天数是无穷的,这样计算很复杂,复杂到算不了。
所以考虑dp,期望E=∑(昨天可以转移到现在状态的所有可能的情况的期望+1)*概率=∑(昨天可以转移到现在状态的所有可能的情况的期望)*概率 +1
一开始我想用dp[i][j]表示已经找到i种bug,j个系统里找到bug,的期望天数,但是这样不能推出来,由【i-1,j】【i,j-1】【i,j】【i-1,j-1】四种状态推的话,需要1天的概率我们知道,但是这四种情况的概率加起来不等于1,也就是还有需要2天3天...的情况,概率很复杂计算更复杂(回到上面的复杂去了)
所以要dp[i][j]表示已经找到i种bug,j个系统里找到bug,离目标还需要的期望天数。
好,如果明天找到一个bug。
它就可以转移到这里:
dp[i+1][j] 不属于i种,属于j个系统之一。 概率为p1=(n-i)/n* j/s 。
dp[i][j+1] 属于i种之一,不属于j个系统。 概率为p2=(s-j)/s* i/n
dp[i+1][j+1] 不属于i种,不属于j个系统。 概率为p3=(n-i)/n*(s-j)/s
dp[i][j] 属于i种之一,属于j个系统之一。 概率为p4=i/n* j/s
也就是比如找到了新种类,已知系统的bug,那明天离到达目标的期望天数就是dp[i+1][j],那就是今天还差dp[i+1][j]+1天。
dp[i][j]就是它找到的没有用的bug,那明天浪费了,那今天还差dp[i][j]+1天。今天和明天的dp[i][j]是一样的。
p1+p2+p3+p4=1,所以有下面这个式子。
dp[i][j]=dp[i+1][j]*p1+dp[i][j+1]*p2+dp[i+1][j+1]*p3+dp[i][j]*p4 +1
移项(我很难理解为什么自己推自己,然后移项这样...)然后变成这样:dp[i][j]= ( n*s + (n-i)*j*dp[i+1,j] + i*(s-j)*dp[i,j+1] + (n-i)*(s-j)*dp[i+1,j+1] )/( n*s - i*j )
我们知道dp[n][s]=0,就是已经到达目标,还需要0天。然后逆推。
代码
#include<cstdio> #define N 1005 double d[N][N]; int main() { int n,s; scanf("%d%d",&n,&s); for(int i=n; i>=0; i--) for(int j=s; j>=0; j--) { if(i!=n||j!=s) d[i][j]=(d[i+1][j]*(n-i)*j+d[i][j+1]*i*(s-j)+d[i+1][j+1]*(n-i)*(s-j)+n*s)/(n*s-i*j); } printf("%.4f",d[0][0]); return 0; }
以上是关于POJ 2096Collecting Bugs 概率期望dp的主要内容,如果未能解决你的问题,请参考以下文章