新千题计划 10#:[杭电 4624] 无穷动(Endless Spin)

2 篇文章 0 订阅
1 篇文章 0 订阅

无穷动(Endless Spin1) n 个白球,每次随机选择一段区间染黑,求使所有球都为黑色的次数期望。

本题解所有内容转自 HDU4624 Endless Spin(概率&&dp) - chanme - 博客园

容斥。 涉及到一个神奇的转化。

  1. 首先要做的是一个题目的转化。如果我定义pi为 恰好i次将区间涂黑的概率,那么显然期望 E = 0 p 0 + 1 p 1 + 2 p 2 + ⋯ E= 0p_0+1p_1+2p_2+\cdots E=0p0+1p1+2p2+ 换一种角度看这个公式,其实这个公式可以这么写
    E = p 1 + p 2 + p 3 + p 4 + p 5 + ⋯ + p 2 + p 3 + p 4 + p 5 + ⋯ + p 3 + p 4 + p 5 + ⋯ E = p1 + p2 + p3 + p4 + p5 + \cdots \\ + p2 + p3 + p4 + p5 + \cdots \\ + p3 + p4 + p5 + \cdots E=p1+p2+p3+p4+p5++p2+p3+p4+p5++p3+p4+p5+
    定义 L i = p i + 1 + p i + 2 + ⋯ L_i=p_{i+1} + p_{i+2} + \cdots Li=pi+1+pi+2+ 那么我们可以把Li理解成覆盖了i次都没有将整个区间涂黑的概率。
    所以 E = L 0 + L 1 + L 2 + ⋯ E=L_0 +L_1 +L_2+\cdots E=L0+L1+L2+
  2. 理解了上面这一点之后我们可以先考虑一种暴力的做法,那就是枚举 2 n 2^n 2n 个最后留下来的点,譬如最后留下来的点是 v 1 , v 2 , v 3 ⋯ v k v_1,v_2,v_3 \cdots v_k v1,v2,v3vk,那么实际上可选的区间只有 [ 1 , v 1 − 1 ] , [ v 1 + 1 , v 2 − 1 ] , [ v 2 + 1 , v 3 − 1 ] ⋯ [1,v_1-1],[v_1+1,v_2-1],[v_2+1,v_3-1]\cdots [1,v11],[v1+1,v21],[v2+1,v31] 那么这里区间的选法就有 A A A 种( A A A 是可以求出来的),要使这些点都能被留下来,那么我们每次选的只能是这 A A A 个区间,因而概率 p = A n ( n + 1 ) / 2 p = \dfrac A{n(n+1)/2} p=n(n+1)/2A. 那么对于 L i L_i Li 来说 L i + = p i ∗ ( − 1 ) k - 1 L_i += p^i* (-1)^{k-1} Li+=pi(1)k1. 之所以要乘 ( − 1 ) k (-1)^k (1)k 是因为这里需要有一个容斥。考虑到 p i p^i pi 的累加和即 p + p 1 + p 2 + ⋯ = 1 1 − p p+p^1 +p^2 +\cdots = \dfrac 1{1-p} p+p1+p2+=1p1 所以对于每个 2 n 2^n 2n,它对最后期望的影响实际上是 1 1 − p ⋅ ( − 1 ) k − 1 \dfrac1{1-p}\cdot(-1)^{k-1} 1p1(1)k1.
  3. 暴力的想法给到了,那么下面就是要优化一下这种做法了,因为我总不可能 2 50 2^{50} 250 枚举所有剩下的点。一个自然的想法是考虑 DP,看上面的式子我们不难发现实际上最后起作用的是 A A A k k k 的奇偶性,而 A A A 的范围是有限的(总的区间个数),那么我们可以定义一个状态 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k] 表示,第 i i i 个点是白点(未被覆盖),且前 i i i 个白点的奇偶性为 j j j,可选区间的个数为 k k k 有多少个子集。 那么对于一个期望值 E n ( n ≥ i ) E_n(n\ge i) En(ni) 来说这个状态对 E n E_n En 的影响实际上是
    可选的区间 A = A = A= 前i个点的可选区间数 + [ i . . n ] + [i..n] +[i..n]这一段为黑的可选区间数 = k + ( n − i + 1 ) ( n − i ) 2 = k+\dfrac{(n-i+1)(n-i)}2 k+2(ni+1)(ni);
    p = A n ( n + 1 ) / 2 E n + = d p [ i ] [ j ] [ k ] ⋅ ( 1 − p ) ∗ ( − 1 ) j − 1 p = \dfrac A{n(n+1)/2} \\E_n += dp[i][j][k]\cdot(1-p)*(-1)^{j-1} p=n(n+1)/2AEn+=dp[i][j][k](1p)(1)j1

核心代码,亦转自原作者。

dp[0][0][0] = 1;
  for (int i = 0; i <= 50; ++i)
    for (int j = 0; j <= (i + 1)*i / 2; ++j) {
      if (dp[i][0][j])
        for (int k = i + 1; k <= 50; ++k)
          dp[k][1][j + (k - i)*(k - i - 1) / 2] += dp[i][0][j];
      if (dp[i][1][j])
        for (int k = i + 1; k <= 50; ++k)
          dp[k][0][j + (k - i)*(k - i-1) / 2] += dp[i][1][j];
      }
 
for (int i = 1; i <= 50; ++i)
  for (int k = 0; k <= i; ++k)
    for (int j = 0; j <= (k + 1)*k / 2; ++j) {
      if (dp[k][0][j]) {
        long double p = (j + (i - k + 1)*(i - k) / 2 + .0) / ((i + 1)*i / 2);
        if (p == 1.0) continue;
        E[i] -= dp[k][0][j] / (1 - p);
      }
      if (dp[k][1][j]){
        long double p = (j + (i - k + 1)*(i - k) / 2 + .0) / ((i + 1)*i / 2);
        if (p == 1.0) { continue; }
        E[i] += dp[k][1][j] / (1 - p);
      }
    }

  1. 为防止老实人纠正,此处的 Spin 应理解为“纺纱”而非“自转”。 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值