ACM算法系列——google code jam 2011 Problem D GoroSort

     题目:http://code.google.com/codejam/contest/dashboard?c=975485#s=p3&a=3

     看了最终的Analysis以后,发现自己当时的思维陷入了一个死胡同。

     错误的想法:

     当时我是这么想的,假设只有两个数字的时候,即 2, 1的情况下,那么拍一次出现的情况为2,1 或者1,2. 则正确排序的情况为1/2。

     假设只有三个全部乱序的情况下(三个数字中,如果一个是正确,两个乱序的情况,按照上面一种情况考虑,如1,3,2,则按住1,然后3,2产生的情况和上面一样。),拍出来的情况有1,2,3.     1,3,2.     2,1,3.      2,3,1.     3,1,2.     3,2,1. 他们的概率都是1/6。 然后其中1,3,2.      2,1,3。       3,2,1. 都已经有一个排好序了,那么只要按住排好序的那个,接着按照两个乱序的情况进行排序,就可以了,因此概率为(1/6+1/6+1/6) * 1/2 = 3/ 12, 两种情况相加,能够排好序的概率为5/12。因此期望值为 2.4次。

     因此可以得出递推公式:

     g(n) =  P(n,n) + p(n, n-2) * g(2) + p(n, n-3) * g(3) + …… + p(n, 1) * g(n-1)。 p表示n个数组中,包含i个完全排序的情况。g(n)表示概率。

     因此这道题目的思路为,先求出不在同一个位置的连通圈,然后每个连通圈独自进行交换。如2 1 4 3. 连通圈为(2,1)(4,3)。先按住其中一组,拍两次,得到1,2 (4,3),再拍两次得到1,2,3,4. 因为平均四次就有答案了。

      代码如下:

 

    当时,觉得自己的想法肯定没有错。结果就是没有办法AC。最后想了4个小时以后,只好放弃了。

    看了Analysis以后,才发现当时的想法,是有点纰漏的。就是我先入为主的认为,按照最小的连通圈进行修正是最好的方案。其次,我只考虑了存在变化的两种情况,而忽视掉了没有变化的情况。如考虑了3个变化里面的全对的1/6的概率,和对一个的3/6的概率,把剩下的两种2/6的概率给忽视了。

    这道题目换一个角度去思考,就会发现世界真的不一样。

    假设N个数组,里面全部都是没有排序好的,那么拍一次,对于数组中任意的数字,拍一次,它落回正确位置的概率为1/N。假设,拍完一次,有I个数字落回了原来的位置,那么对于没有落回原来位置的数字肯定没有落在这I个数字的位置上,如果落在了这I个数字的上面,则这I个数字肯定就是错误的,因此概率为(N-I)/N,接下来,按住I个正确的,拍一次,落回原来位置的概率为1/N-I,两者相乘的概率依然为1/N,因此一个数组正确排序的期望为整个数组中没有正确排序的数字。具体比较严格的证明,大家就看分析吧。我也只看懂了一点点,哈哈……

     代码相当简洁啊!

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值