CF#829 E. Wish I Knew How to Sort(概率DP)

给出一个由 0 0 0 1 1 1构成的序列,希望它从小到大有序。排序的方式是:完全随机的选 x x x y y y ( x < y ) (x<y) (x<y),如果有 a x > a y a_x>a_y ax>ay交换两数。问希望的次数。

一个DP式子推出来就能秒的题目。

状态设计非常重要,记数列中0出现的次数为 s 0 s0 s0,1出现的次数为 s 1 s1 s1。很显然最终前s0个数是0,后s1个是1。

f [ i ]   f[i]\, f[i]=前s0个数中有i个1的期望步数。

如果记原数列中前s0个数中1的个数为cnt, f [ c n t ] = 0 f[cnt] = 0 f[cnt]=0


考虑转移方程

对于f[i]的情况,考虑做了有效交换。

共有 ( n + 1 ) ∗ n / 2 (n + 1) * n / 2 (n+1)n/2种交换情况,前s0个数中有 i + 1 i+1 i+1个1,后s1个数中算得有 i + 1 i+1 i+1个0,有效的交换有 ( i + 1 ) 2 (i+1)^2 (i+1)2种。所以有 ( i + 1 ) 2 ( n + 1 ) ∗ n / 2 \frac{(i+1)^2}{(n + 1) * n / 2} (n+1)n/2(i+1)2的可能从 f [ i + 1 ] f[i+1] f[i+1]转移过来。

除此之外,只有从 f [ i ] f[i] f[i]转移过来了。

这两种转移下,都增加了1的操作

列出式子
f [ i ] = ( i + 1 ) 2 ( n + 1 ) ∗ n / 2 f [ i + 1 ] + ( 1 − ( i + 1 ) 2 ( n + 1 ) ∗ n / 2 ) f [ i ] + 1 f[i] = \frac{(i+1)^2}{(n + 1) * n / 2}f[i+1] + (1-\frac{(i+1)^2}{(n + 1) * n / 2})f[i] + 1 f[i]=(n+1)n/2(i+1)2f[i+1]+(1(n+1)n/2(i+1)2)f[i]+1
稍稍化简就大功告成啦~~
f [ i ] = f [ i + 1 ] + ( n + 1 ) ∗ n / 2 ( i + 1 ) 2 f[i] = f[i+1] + \frac{(n + 1) * n / 2}{(i+1)^2} f[i]=f[i+1]+(i+1)2(n+1)n/2


以下内容没有什么实际意义,为个人思考记录

我的思考

f[cnt]的状态下会自己转移到自己,所以出现cnt这个状态的期望步数肯定不是0,为什么开头赋值0了呢?

原来是我对f[i]理解存在偏差,应该是第一次抵达i时的期望步数。这样一来,f[0]才是答案表达的意思。f[cnt]自然也是0了,因为一开始就抵达了cnt这种状态。

我的错误

在计算转移的总概率时,我把可行转移方案的概率算成是 i s 0 i s 1 \frac{i}{s0}\frac{i}{s1} s0is1i。犯了两个错误,一是只算了选择的数字是在s0和s1中,忽视了两个都在s0和两个都在s1中的情况。二是应该在f[i+1]下考虑这个问题,i应该取i+1。

代码就不需要了吧:)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值