zoukankan      html  css  js  c++  java
  • 【loj6191】「美团 CodeM 复赛」配对游戏

    题目

    显然期望dp。

    简单想法:

    f[i][j]表示前i个人中向右看并且没有被消除的人数的概率

    如果第i+1个人是向右,$f[i+1][j+1]=f[i][j]/2$

    如果第i+1个人是向左,$f[i+1][j-1]=f[i][j]/2$

    最后期望总和是$sum_{i=0}^{n} i*f[n][i]$

    转移没有问题,但容易发现这样算出来的期望剩余人数没有算上向左看的。

    什么意思呢?我们都知道期望=数量(人数)*概率,但这里dp只设了向右看的人数状态,虽然也包括了所有向左看的情况,但最后算期望的时候,每种向右看的人数情况的概率所乘的人数 只有向右看的而没有向左看的,这样就忽略了最终剩下的向左看的人数对期望的影响。

    比如当j=0,也就是向右看的人数为0时,期望=向右看人数*概率=0*概率=0,但很明显这种情况下向左看的人数还有很多种情况,它们的人数并没有被算上。

    但稍微一观察就会发现,向右看和向左看的情况好像是一样的,因此最终期望就等于之前算出的期望总和*2。

    这又是什么意思?要把向左看的人算上,还得设个g[i][j]表示前i个人中向左看并且没有被消除的人数的概率,然后转移和期望求和方法与向右看的相同,只是这样的话期望剩余人数就只算上了向左看的而没算上向右看的

    那么期望和就是$sum_{i=0}^{n} i*(f[n][i]+g[n][i])$

    也就是说要证明f[n][i]=g[n][i],才能证明向右看的答案*2是正确的。

    我们知道,最后剩下的人一定是前一段向左看,后一段向右看,比如<<<>>>>。中间被消掉的一定都是有相对关系的。

    那把剩下的人的序列完全对称,得到这个对称序列的概率和对称前是相等的。

    就上面那个例子,对称后就得到了<<<<>>>,与原序列<<<>>>>的出现概率相等,只是把向右看的都改为放向左看的,反之亦然而已。数学化地讲:两序列dp形式分别是$f[n][4]$和$g[n][4]$,而两个式子的转移方法相同,所以是等价的。

    而每种向右看的情况都对应一种向左看的情况(只要对称就得到了这样一种合法情况),前者向右看的人数和后者向左看的人数相等,即$f[n][i]=g[n][i] | 0leq i leq n$。得证。

    所以答案为$(sum_{i=0}^{n} i*f[n][i])*2$

    如果没发现对称性,可以直接设期望,比如这篇博客。也可以自行百度其他 dp设期望 的方式。

    代码过短不放了

  • 相关阅读:
    Java实现 LeetCode 394 字符串解码
    Java实现 LeetCode 394 字符串解码
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 390 消除游戏
    Java实现 LeetCode 390 消除游戏
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/loj6191.html
Copyright © 2011-2022 走看看