zoukankan      html  css  js  c++  java
  • [机房测试]冒泡排序期望

    Description

    一个长为 \(n\) 的排列的花费是使其排好序所要冒泡的次数。

        for(int i=1;i<n;i++)
            if(a[i]>a[i+1]) swap(a[i],a[i+1]);
    

    求随机一个长为 \(n\) 的排列,花费的期望。

    Solution

    一个显然的做法是枚举花费,然后统计每种花费的排列个数。根据冒泡排序的性质,每次会使得最大的没有沉底的数沉底,如果对于一个数,前面存在比它大的,那么在一次排序操作后,个数一定会减一。定义 \(f_i\) 表示在 \(i\) 前面且比 \(i\) 大的数的个数,那么一个特定排列的花费就是 \(\max\{f_i\}\)、再次观察,可以发现,\(f\) 序列和实际排列构成一个双射关系。通过平衡树可以从大到小还原排列。也就是说,我们可以直接对 \(f\) 序列进行计数。那么只需要保证 \(\forall i,f_i\leq \min(i-1,k)\) 就行了。但这样求出来的实际上是 \(\max\{f_i\}\leq k\) 的方案,需要差分一下,就可以得到

    \[f(n,k)=k!((k+1)^{n-k}-k^{n-k}) \]

  • 相关阅读:
    uva299 Train Swapping
    uva 10106 Product
    uva 340 MasterMind Hints
    uva 10115 Automatic Editing
    uva748 Exponentiation
    uva152 Tree's a Crowd
    uva 10420 List of Conquests
    uva 644 Immediate Decodability
    要知其所以然的学习(转载)
    持有书籍统计
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15423193.html
Copyright © 2011-2022 走看看