概率/期望 [常规部分]

前言

大概就是拿着一些普通的题目扯淡一下?
绝大部分来自BZOJ
因为是大部分是中文题所以放个链接,不占过大篇幅qwq

题目

HDU2955

看起来非常的像一个背包,但是费用是实数的话是很难存并且实现的。所以考虑令DP[x] 表示已经获得了x的最小风险。
然后在最后找答案的时候判断一下当前最大的x满足dp[x]满足风险要求。
Tag:DP
Code


BZOJ1076

对于当前状态可以简单表示为当前已经获得了哪一些物品[可以二进制的简单表示],已经扔了了多少物品,显然只有这两个东西就可以求出下一步的状态并且及时停下。
接下来的说法可能会有一点混乱。

简单来说就是令dp[s][i] 表示当前已经获得的物品的集合的表示为s,当前已经扔出了i个东西,那么我们等概率的获得所有的物品,那么对于当前的这个物品是选择还是不选择呢?

听起来似乎非常的复杂,但是事实上,只要考虑选择更优还是不选择更优就好了,也就是记忆化搜索[其实在这里写成递推一样的形式也是可以的,只是稍微有些麻烦[个人看法]],然后记忆化搜索的话就很好考虑了,考虑选择或者不选择哪个更加优秀就选择哪一种方案即可。
Tag:DP
Code


BZOJ1415

题意的话就是聪聪朝着可可走两步,然后可可随机的走一步或者不动。这样就可以发现游戏一定是在有限步数内完成的,聪聪可可每过一轮距离至少会变近1,至多会变近3,不过简单来说就是,状态之间没有环。
那么就可以简单的转移啦。然后记忆化搜索的效果也非常好,代码短而优美[虽然我的大概算不上]。
Code


BZOJ2438

JC一定是有一个特殊的最优的询问方案的,那么问题来了,这个询问方案是什么呢?贪心的考虑,肯定询问的人越少越好。
每次查到一个人之后,那么他能到达的所有人包括他自身都是可以被被确定下来的。很容易想到首先Tarjan来缩点,然后每次查询就一定为入度为0的点。
但是,事情没有那么简单。如果一个JC已经确定了n-1个人的身份了,然而却没有人认识最后一个人。小镇只有一个杀手,在这答案已经呼之欲出的时候,还需要查这个人吗?
答案是显然不需要。
所以需要查的个数就等于,入度为0的联通块的个数,如果存在一个入度为0,大小为1,而且所有能到达的联通块都可以被其他联通块到达的联通块,那么需要查找的个数减去1。
Tag:贪心,Tarjan
Code


BZOJ2752

简单来说就是考虑一个点的贡献是多少?是它的值*它被包含的方案数量。
对于dis[x,x+1]会被算到 (xl+1)(r(x+1)+1) ( x − l + 1 ) ∗ ( r − ( x + 1 ) + 1 )
然后怒推一波式子,用线段树维护一波就结束了。但是似乎当时写的版本会比较复杂?

但是这个不好解决。换个表达方法[?]
维护一个前缀和
n=r-l
sum[r]n+sum[r1](n1)...+sum[l+1]1sum[l]nsum[l+1](n1)...sum[r1]1 s u m [ r ] ∗ n + s u m [ r − 1 ] ∗ ( n − 1 ) . . . + s u m [ l + 1 ] ∗ 1 − s u m [ l ] ∗ n − s u m [ l + 1 ] ∗ ( n − 1 ) . . . − s u m [ r − 1 ] ∗ 1

dis[l][r]=T1.qu(l,r)T3.qu(l,r)lT2.qu(l,r)T3.qu(l,r)(r2l) d i s [ l ] [ r ] = T 1. q u ( l , r ) − T 3. q u ( l , r ) ∗ l − T 2. q u ( l , r ) − T 3. q u ( l , r ) ∗ ( r − 2 ∗ l )
这个可以用线段树解决的,不过稍微有点麻烦,不过其实差不多了。
需要一个等差数列合并,不会,所以用很玄妙的方法写了。

sum[x] 表示从节点1走到节点x的距离是多少,那么对于区间[l,r]的答案就会是

x=lr1y=x+1rsum[y]sum[x] ∑ x = l r − 1 ∑ y = x + 1 r s u m [ y ] − s u m [ x ]

然后用线段树暴力维护[?]
对于上面这个式子,其实可以拆开,然后分别统计
r1x=1(rx)sum[x] ∑ x = 1 r − 1 ( r − x ) ∗ s u m [ x ] ry=l+1(yl)sum[y] ∑ y = l + 1 r ( y − l ) ∗ s u m [ y ]
然后真的可以用线段树暴力维护了。
对于区间加的过程中怎么快速求出对于各区间的贡献,虽然说可以通过数学来推出公式,不过也可以通过预处理来解决。
Code
Tag:数据结构维护计数问题


BZOJ3566

是树形DP吧…没了。
考虑有可能是父节点的向下导。
再记一个f[x] 表示如果点亮f[x]的父亲之后可以往下点亮多少个的期望.
f[x] 表示节点x是被儿子节点导上来的。
g[x] 表示节点x被点亮带来的贡献
F=1(1f[x])/(1f[e[i].x]e[i].l); F = 1 − ( 1 − f [ x ] ) / ( 1 − f [ e [ i ] . x ] ∗ e [ i ] . l ) ;
P(A+B)=P(A)+P(B)P(A)P(B) P ( A + B ) = P ( A ) + P ( B ) − P ( A ) ∗ P ( B )
P(A+BB)=(P(A+B)P(B))/(1P(B)) P ( A + B − B ) = ( P ( A + B ) − P ( B ) ) / ( 1 − P ( B ) )
参考了这位
Tag:树形DP


BZOJ1419

dp[x][y] 表示翻到了x张红,y张黑。然后记忆化搜索。非常传统的做法。
然后注意的地方是:
会炸空间,滚动数组。

不过打表似乎有一定的规律,说不定有什么优化方法?如果有的话求教qwq
Tag:DP


BZOJ3191

是一个约瑟夫环问题。之前接触的并不多,不过似乎有一定的套路。
dp[i][j] 表示有i个人在游戏,第j个人胜利的概率
然后就可以简单的推得对于本题的转移
dp[i+1][(j+a[k]) d p [ i + 1 ] [ ( j + a [ k ] )
不过这样有一定套路可沿的问题倒是可以专门在整理xxx
Tag:DP


BZOJ3091

对于这种把一模一样的问题强行丢到树上表示强烈谴责。其实感觉就是BZOJ2752啊qwq。
然后打了一个LCT来解决就好了。当时还把LCT打错了…然后这里用的做法就是直接用dis[x,x+1]会被算到(x-l+1)*(r-(x+1)+1)的性质来求了。需要同时维护好几个东西…
lsum=1a1+2a2+...+nan l s u m = 1 ∗ a 1 + 2 ∗ a 2 + . . . + n ∗ a n
rsum=1an+2an1+...+na1 r s u m = 1 ∗ a n + 2 ∗ a n − 1 + . . . + n ∗ a 1
fp=fls+frs+lsumls(szrs+1)+rsumrs(szls+1) f p = f l s + f r s + l s u m l s ∗ ( s z r s + 1 ) + r s u m r s ∗ ( s z l s + 1 )
Tag:LCT,树上计数问题
Code


BZOJ1426

dp[x] 表示收集了x张不同的邮票的期望用钱数量
sum[x] 表示期望收集次数(决定花钱的数量)
step=n/(ni) s t e p = n / ( n − i )
sum[i+1]=sum[i]+step s u m [ i + 1 ] = s u m [ i ] + s t e p
基础的式子
dp[i]=(dp[i+1]+sum[i+1])(1i/n)+(i/n)(dp[i]+sum[i+1]) d p [ i ] = ( d p [ i + 1 ] + s u m [ i + 1 ] ) ∗ ( 1 − i / n ) + ( i / n ) ∗ ( d p [ i ] + s u m [ i + 1 ] )
然后移项
dp[i+1]=(dp[i](i/n)(dp[i]+sum[i+1]))/((ni)/n)sum[i+1] d p [ i + 1 ] = ( d p [ i ] − ( i / n ) ∗ ( d p [ i ] + s u m [ i + 1 ] ) ) / ( ( n − i ) / n ) − s u m [ i + 1 ]
Tag:DP?


BZOJ4832

dp[x][cnt1][cnt2][cnt3][hp] 表示攻击了x轮,血量扣除了hp,血量为1的奴隶主个数为cnt1,之后以此类推的概率。
一种简单易懂的状态…不过并不优。
如果把存的概率改成期望扣血量,那么就可以省一维。然后如果轮数表示剩余多少轮,然后就不用每个T都计算…一下子就只跑4ms了呢。
Tag:DP


BZOJ3029

可以发现,要求满足的只有
1.需要胜利l场;
2.背包容量大于碎片个数
对于第一个要求只需要dp多记录一维当前胜利场数,对于第二个要求,发现胜利给的背包容量可能会很大,但是最多只会用到获得碎片个数个容量。

然后就记dp[x][l][p] 表示前x场已经结束,胜利了l场,min(最大碎片获得数量,背包容量-世纪碎片获得数量)=p的概率。
然后就没有了?对于最后一维可能为负值,只需要加上一个base即可。
Tag:DP


BZOJ2510

简单来说就是一个类似于矩阵乘法快速幂的东西,事实上除了概率/期望DP以外这种做法也非常的常见。
所以说看到这道题我们考虑当前已经进行2^K次操作,dp[l] 为编号为x的球到x+l位置的概率是多少。
然后p[x] 表示位置在x的球的期望个数。
Tag:快速幂


BZOJ1417

首先我们可以发现我们不考虑块里面到底有什么和块内的联通情况,需要考虑的只有所有块的大小。那么考虑状态内记各个块的大小。然后可以用map来解决。
那么对于当前状态,设有m个块,每个块的大小分别为a[1],a[2]…a[m], mi=1C2a[i] ∑ i = 1 m C a [ i ] 2 种情况不发生改变,以及 a[x]a[y] a [ x ] ∗ a [ y ] 种情况,x和y合并。
然后 dp[s]=(dp[ns]p[ns]+dp[s]mi=1C2a[i])/C2n+1 d p [ s ] = ( ∑ d p [ n s ] ∗ p [ n s ] + d p [ s ] ∗ ∑ i = 1 m C a [ i ] 2 ) / C n 2 + 1
之后移项。使用记忆化搜索方便的求出答案。
关于复杂度,可以写一个普通的深搜,搜出将30分成数个部分的方案数,是4565(大概不会算错?)
Tag:记忆化搜索


BZOJ2676

首先看到这一类问题,先考虑转化成二分然后变成判定问题这样的话就简单很多了[?]
那么对于当前的p,需要快速的求出期望获得的得分。N比较大,能接受的要么是 O(log2n) O ( l o g 2 n ) 要么 O(n1/2) O ( n 1 / 2 ) ,看起来前者的可能性比较大。
然后猜测就是到这里为止。
由于每一关的结构都是类似的[也可以说是转移方程],想到矩阵乘法快速幂,然后这样也可以有效的把N带来的复杂度减小。然后这样可以不可以呢?答案是可以的。
状态数量只有R*Q,表示当前连胜场数和当前的血量。然后矩阵乘法也可以接受。就解决问题了。

需要注意的地方:
S要开long long!!!
Tag:矩阵乘法,快速幂


BZOJ2318

如果当前投出正面更优 那么就想投出正面,否则想投出反面。
令f[n] 表示当前石子数量为n先手胜率,g[n] 表示当前式子数量为n的后手胜率。

考虑之后状态的胜利概率,然后再转移。
然后就是n特别大可以直接缩小。因为之后的概率几乎不变。
Tag: 博弈[?]

总结

这里整理的是一些较为简单[?]并不利用期望的线性性质[也不一定?]并且状态之间没有环[不包括自环?]的概率/期望DP,和一些表面并不是DP,但是实际上和概率/期望有着较大联系的题目。
那么可以分为这么几类。
1. 可能会延伸出一些比较特别的形式:
- 特殊期望模型
- BZOJ1426
- 价值作为下标[DP常见]
- HDU2955
- 快速幂
- BZOJ2510
- BZOJ2676
- 记忆化搜索后取最优决策 (某种意义上可以算博弈?)
- BZOJ1076
- BZOJ2318
- 某些状态到达的概率很小可以忽略
- 那道题好像被归到期望线性性质里去了
- 二分转为判定问题
- BZOJ2676
- 特殊模型
- BZOJ3191(约瑟夫环)
- 滚动数组[其实这个也没啥?]
- BZOJ1419

2.图论
- BZOJ2438

3.计数问题
- BZOJ2752
- BZOJ3091

总之这样的题目大部分情况下通过推一推公式或者转移方程,或者理解题意之后都比较简单?与其说是考概率/期望多一点,不如说是考其他知识点的时候顺带一下概率。当然和特别复杂的算法结合在一起也能出很难的题目吧?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值