tag:概率dp
思路:关于期望的问题
除了上次多校之外好像没接触过期望类的问题,最近看了刘汝佳的厚白书上几个题,对马尔可夫过程完全不理解,同时也不明白所谓的”期望的线性和全期望公式“是啥。。。
不过看了上次某篇博客里说”一般情况概率是正着推,期望是倒着推”(尼玛,老子怎么揣测就不对,我怎么知道for循环式正着过去,还是逆着过来)
算了 不扯淡了 慢慢看吧 总会理解别人说的那几句话的
同白书143面那个马尔可夫过程那题一样,那个题是得到这样一个等式 f(x)=1+f(x)*(1-g(x)/p(x))+sum(f(x/y))*1/p(x) (x能整除y) (f(x)表示最后得到1的期望)
同理,那么这题的等式为:
设dp[i][j]为已经发现i个bug,类属于j个bug的时候消除其余的bug所要的天数期望
dp[i][j] = 1 + dp[i+1][j] *(n-i)/n*j/s + dp[i+1][j+1]*(n-i)*(s-j) /s + dp[i][j+1]*i/n*(s-j)/s + dp[i][j]*i/n*j/s
化简之后得到:
dp[i][j] = ( dp[i+1][j] *(n-i)/n*j/s + dp[i+1][j+1]*(n-i)*(s-j) /s + dp[i][j+1]*i/n*(s-j)/s )/ (1 - i/n * j/s)
至于为什么这个题的for循环是逆着的,这个吃夜宵的时候想通了,开始的时候呢(假设dp[i][j] 表示消除全部bug的概率,求个倒数不就是期望了?我想的是从每一个状态到另外四个相邻状态的关系可以有个递推,可是for循环怎么写呢,尤其是那种从自己到自己的情况该怎么写呢。= = 我是不是太天真了。)看了下别人的代码,联想到白书上那道求期望的,= = 尼玛,不跟书上是一个意思么,至于为什么逆着,是因为开始的时候已经解决n种bug和s种子系统的情况需要解决其余的bug的期望(已经没有需要解决的bug了)是0,然后一直推到bug数和子系统数为0的情况。
呵呵。。。别人眼里的大水题,我竟然搞了这么久,这算是入门题么 = =
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
double dp[1010][1010];
int main()
{
int s,n;
while(scanf("%d%d",&n,&s)!=EOF)
{
dp[n][s]=0;
for(int i=n;i>=0;i--)
for(int j=s;j>=0;j--)
{
if(i==n&&j==s)
continue;
dp[i][j]=(1+
dp[i+1][j]*(n-i+0.0)/n*j/s+
dp[i+1][j+1]*(n-i+0.0)/n*(s-j+0.0)/s+
dp[i][j+1]*(i+0.0)/n*(s-j)/s)/(1-(i*j+0.0)/(n*s+0.0));
}
printf("%.4lf\n",dp[0][0]);
}
return 0;
}