标签:表示 思考 不能 src 超出 计算 inline alt 范围
虽然概率DP有许多数学期望的知识,但是终究无法偏离动态规划的主题。动态规划该有的特点继续保留,另外增添了一些概率期望的神秘色彩。
[1]机器人
·述题意:
多组输入n,m,l,r。表示在一个环上有n个格子。接下来输入m个w表示连续的一段命令,每个w表示机器人沿顺时针或者逆时针方向前进w格,已知机器人是从1号点出发的,输出最后机器人停在环上[l,r]区间的概率。n(1≤n≤200) ,m(0≤m≤1,000,000)。
·分析:
这是一道求概率的题吗?是的。我们可以想象机器人从1点开始,每次分身前往距离为wi的两点,最后呢就会有很多很多分身,落得到处都是,然后呢统计在[l,r]的分身个数,再除以总个数就是概率呀……
其实这类问题正是这样做的——计算出每种情况占种情况的概率,然后回答问题。不过呢为了统一格式,所以在网上见到解法,都是机器人一分为二变成两个0.5机器人而不是变成两个和原来一样的机器人。总结而言,0.5机器人就是概率的体现。
如果我们使用f[i]表示i这个位置会出现多少个机器人分身,那么机器人所在点是这样为周围贡献答案的:
经历了上述美妙的形象化理解后,这道题的状态转移就很明显了:
①刷表法: f[i-w]+=f[i]*0.5 , f[i+w]+=f[i]*0.5
②填表法: f[i]=f[i-w]*0.5+f[i+w]*0.5
最后一个小提醒是,由于这道题是环形问题,所以呢如果超出了范围,可以进行取模或者特判来维持正确的转移。
代码在这里:
[2]收集漏洞
·述题意:
输入n,s表示这里存在n种漏洞和s个系统(0<n,s<=1000)。工程师可以花费一天去找出一个漏洞——这个漏洞可以是以前出现过的种类,也可能是未曾出现过的种类,同时,这个漏洞出现在每个系统的概率相同。要求得出找到n种漏洞,并且在每个系统中均发现漏洞的期望天数。
·分析:
这是一道求期望值的题目。题目中的两个关键字提醒我们二维状态设计或许很美妙。根据上题的路子,我们用状态f[i][j]表示已经发现了i种漏洞同时已经有j个系统发现了漏洞的情况下最终达到题目要求(f[n][s])的期望天数。
进一步。由题目可知,其实每次漏洞有两种情况(发现过的漏洞和新的漏洞),同时这个漏洞所在的系统也有两种情况(之前已经发现漏洞的系统和之前没有发现漏洞的系统),所以组合一下,共有四情况,一起来转移吧:
由图,我们可以轻松得到转移方程吗?还差一丢丢。因为目的是求出期望值——什么是期望值?好吧,暂时可以理解为“权值 x 概率”。因此期望Dp的转移是有代价的,而不像概率Dp那样简单统计了。另外一个问题,类似于上文的机器人分身,当前状态的期望值有多个转移方向,所以此处要乘上概率——也就是选择这一步的概率P,如下:
f[i][j]—>f[i+1][j+1]: P1=(n-i)*(s-j)/n*s
f[i][j]—>f[i+1][j] : P2=(n-i)*j /n*s
f[i][j]—>f[i][j+1] : P3=i*(s-j) /n*s
f[i][j]—>f[i][j] : P4=i*j /n*s
然后算上转移的代价(1天),我们开始思考最终的DP转移方程式。这里我们将f[n][s]=0定为边界——很合理,表示找到n种漏洞,有s个系统发现漏洞距离目标状态的期望天数(就是一样的状态,所以期望天数是0啊)。据此我们设计出一个逆推的Dp方程式:
f[i][j]=
(f[i][j]+1)*P4+(f[i][j+1]+1)*P3+(f[i+1][j]+1)*P2+(f[i+1][j+1]+1)*P1
你会发现方程左右两边都有f[i][j],所以就对式子进行化简。化简如下:
f[i][j]=f[i][j]*P4+f[i][j+1]*P3+f[i+1][j]*P2+f[i+1][j+1]*P1+(P1+P2+P3+P4)
f[i][j]*(1-P4) = f[i][j+1]*P3+f[i+1][j]*P2+f[i+1][j+1]*P1 + 1
最终就是将左边系数除过去然后带入p1p2p3p4,逆推转移就是了,答案当然就在f[0][0]诞生啦,代码也来啦:
一个补充问题:为什么期望dp常常逆推?大米饼认为期望DP中状态转移各个去向的概率决定了这一点。如果要求解,我们必须要知道转移去向的概率是多少(就像上文发现漏洞的四种情况具有不同的概率一样),也就相当于机器人分身。那么逆推情况下,各个来源的概率正是实际问题中的概率(比如漏洞是新的且在新系统就是(n-i)*(s-j)/n*s)。如果顺推,由于一些来源状态无法到达或者无实际意义,很多时候转移的概率并不是实际问题的概率。更加浅显易懂地说就是:逆推的概率符合实际,顺推的概率只是形式上的(即填表法得出刷表法),不一定符合实际。
[3]一个人的游戏
·述大意:
有三个骰子,分别有k1,k2,k3个面,初始分数是0。第i骰子上的分数从1道ki。当掷三个骰子的点数分别为a,b,c的时候,分数清零,否则分数加上三个骰子的点数和,当分数>n的时候结束。求需要掷骰子的次数的期望。
(0<=n<= 500,1<K1,K2,K3<=6,1<=a<=K1,1<=b<=K2,1<=c<=K3)
·分析:
这是一道求期望的题。首先总体感悟一下可以知道状态有两类转移途径,分别是加分数和清空分数。还是像以前一样,我们定义f[i]表示当前分数为i的时候,到达大于等于n分数的状态的期望次数。对于清空情况的概率我们使用P0表示。
首先,由于我们已知三个骰子可能的点数,那么我们可以算出所有可能分数的概率,即用p[i]表示三个骰子加起来分数为i的概率。
上文的处理使得DP方程式很容易写出来:
然后就轻轻地写出DP方程式(注意,还是逆推):
f[i] = f[0]*P0 + ∑(f[i+k]*p[i+k]) + 1
看上去问题已经解决,但是出现了一个很大的问题:逆推是从大的i循环至小的i,但是现在每个式子都含有一个f[0],这样就没有办法转移状态了(似乎形成了一个环,然后在其中迷失自我) 。
怎么办啊?啊啊啊,完了完了。
还没完!既然f[0]违背常理,我们不能立刻求出来,那么就将它作为未知数好了。首先我们找出每个方程式的统一格式,可以写成这样:
f[i]= f[0]*ai + bi (原因是每个式子都含有f[0])
那么对于上面的方程式,其中的f[i+k]就可以被拆成:
f[i+k]=f[0]*ai+k+bi+k
然后带入原来的式子得出:
标签:表示 思考 不能 src 超出 计算 inline alt 范围
原文地址:http://www.cnblogs.com/Paul-Guderian/p/7624039.html