再次刷概率DP,慢更
随便找了个VJ上的概率DP专题刷,之前也没写过概率DP的博客,顺便搞了
目前总结:
期望方程好写,想后继即可
概率方程也是想后继,不过
概率题的答案概率不一定有明显的状态转移,
或者题目有明显的状态转移但是跟答案没什么关系
或者有明显的状态转移但是不知道怎么表示后继
这种题目的明显状态转移肯定是正解的一部分,往这方向想准没错
不虚,二维维护信息不够就开三维
DP注意边界处理
解DP:
待定系数(固定回到某个点,比如dp[1]),高斯消元(DP成环),直接递推
WA点:
精度控制,DP卡空间,极端数据(很逼近1,0那种),重置DP数组
树上概率DP可以分叶子与非叶子的方程
大胆假设状态,小心论证转移
POJ2096:
题意:
一个bug属于A类型(共n),属于B类型(共s)的一种,问集齐所有类型bug的天数的期望
思路:
dp[i][j]:已集齐i种A,j种B后还需要的天数的期望。
方程就是当前状态的后继。今天干的事情可以用后继表示
dp[i][j]=p(今天收到之前没集齐到的A类型&&今天收到之前没集齐到的B类型)*dp[i+1][j+1]
+p(今天收到已有的A&&今天收到已有的B)*dp[i][j]
+p(今天收到旧A&&今天收到新B)*dp[i][j+1]
+p(今天收到新A&&今天收到旧B)*dp[i+1][j]
+1
边界:dp[n][s]=0,我们选择倒着维护出dp[0][0]
+1是因为不管今天干了什么,都要算上1天
ZOJ3329
题意:
3个骰子分别k1,k2,k3面,不断记录,并累加骰子朝上的数字和sum,
如果第一个骰子扔到a,第二个骰子扔到 b,第三个骰子扔到 c,累加和归0,
若累加和>n,游戏结束
问游戏结束时扔的次数的期望思路:
dp[i]:当前累加和是i 还需要扔的次数的期望是dp[i]
容易想到dp[i]的后继 :dp[i]= p0*dp[0]+sigma(pk*dp[i+k])+1;
+1是因为不管今天扔了什么,都要算上一次
p0指归0的概率,最后输出dp0
方程出来了。。但是每项都有dp0不能倒序递推,
要么就高斯消元,要么就是待定系数法
待定系数dp[i]=a[i]*dp[0]+b[i];
我们要把dp[i+k]用待定系数的方式表示,最后
a[i]=p0+sigma(pk*a[i+k])
b[i]=1+sigma(pk(b[i+k])
预处理pk,倒序维护出ai,bi即可
难度:0.6
HDU4405
题意:
从0出发,>=n结束,m个跳跃点,可跳可不跳,跳到一个地方还可连续跳(不耗次数)
问最少步数的期望
思路:
dp[i]为i出发的最少步数的期望,考虑贪心,能跳尽量跳,显然dp[i]=sig(dp[get(i+k)])+1,1<=k<=6
get(i)是返回点i能跳的最大点,有点像并查集维护祖先那种感觉,预处理一下就好了
难度:0.5
HDU4089
题意:
迷宫,给一颗树,每个节点一定概率结束,一定概率回到点1,一定概率走到邻接点
嘛,容易写出以下方程,dp[u]=ku*dp[1]+ei*0+(1-eu-ku)/tot*sigma(dp[v]+1)
这种就很蛋疼,通过上一题知道是待定系数法,但是树形不知道怎么待定,看了波题解,
自己多推几遍就熟了
思路经验:
待定系数法求解,转为dp[u]=au*dp[u]+bu*da[fa[u]]+cu的形式,
分为叶子与非叶子,因为叶子的dp[u]直接就是上面的形式
非叶子的dp[sonu]用上面的柿子带进去,最后能得到au跟av的递推式,
DFS跑一下即可,eps取1e-8WA
难度:0.85
hdu3853
题意:
左上角1,1走到右下角n,m,pij1概率原地,pij2概率向下,pij3概率向右,每次2花费
问最后走到右下角的期望花费,
思路:
枚举ij后继,dpij=pij1*dpij+pij2*dp[i,j+1]+pij3*dp[i+1,j]+2,边界dp[n][m]=0
WA点:极限数据,pij1有可能很接近1,那么该点dp[i][j]=inf;???这里改成0才能过,题目有错吧
一开始把p2,p3搞反了QAQ
难度0.5
POJ2151
题意:
问每个队伍均A至少1题,冠军队A至少N题的概率
思路:
第一反应是有s[i][j]表示前i支队伍a了至多j题的概率
均A至少1题的概率就是mul(1-s[i][0]) i<=T
均A 1~N-1题的概率就是mul(s[i][N-1]-s[i][0]) i<=T
答案就是这两个相减
然而sij并没有明显的状态转移,至少跟s[i-1][j]没关系
。。。然后就懵了
注意到:
s[i][j] 是由队伍i A了0题的概率+队伍i A了1题的概率+...队伍i A了j题的概率
对于s[i][j],我们要想怎么求出队伍i 在M题里A出 x题的概率 x<=j
不妨设dp[i][j][k]:队伍i在前j题里A出K道的概率
为什么要这样设呢,因为dp[i][j-1]跟dp[i][j]有关系,经验啊!
状态转移:dp[i][j][k]=p[i][j]*dp[i][j-1][k-1]+(1-p[i][j])*dp[i][j-1][k];
边界:dp[i][0][0]=1.0;dp[i][j][0]=dp[i][j-1][0]*(1-p[i][j])
3重循环求解即可,这里用滚动数组可以压空间
难度:0.80
Codeforce148D
题意:
思路:
设dp[i][j]为剩i只白鼠,j只黑鼠的女王获胜的概率,这样设可以得到后继的表示
边界dp[i][0],dp[i][1],dp[i][2]手推一下。。
难度0.6
hdu4336
题意:
N种卡片,开包得到卡片的概率分别为PI,开包可能得到一张或没有卡片
问集齐卡片的期望,N<=20
思路:
由于得到卡片的概率不一定相等,所以不能够设dp[i]:当前集齐的i张卡片,来枚举后继。
注意到卡片N<=20,我们可以用(二进制状态)S表示集齐的状态
那么设DP【S】为还需集齐(S中的1代表未集齐的卡,0代表已经集齐)的卡片
边界DP【0】=0,DP【11111....】是答案,枚举后继
DP【S】=sigma(DP【抽到没抽到的卡:S-(第k种卡,且S还没抽到第k种卡)】*pk)
+sigma(DP【S】*p2)+1
p2指抽过或者空包的概率,+1是指不管开到什么卡,都要算开了一次包
网上题解大部分都是反过来DP,感觉不太好理解
i&(1<<j)!=0即可,不需要i&(1<<j)==1,位运算太菜了orz
难度:0.6