项目中的有趣题目 -- 吃饺子问题

本文介绍了一个有趣的项目题目:桌上100个饺子中有10个包了硬币,求连续吃到硬币的期望次数。通过动态规划(DP)策略,解析了如何定义状态和递推公式,并提出了一种节省空间的解决方案,以适应大规模数据的计算需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

近日,项目中偶遇一个有趣的题目,感慨多多,备忘之。抽象出来,大致是:

桌上一共有100个饺子,其中有10个饺子包了硬币,问:连续吃到硬币的期望次数是多少次?

首先,定义一下这里的连续,如果我们将吃饺子的顺序抽象为一个100位的二进制数。并且吃到饺子表示为1,没吃到则为0,那么:
  • 如果一次和第二次吃到,那么可表示为: 110.....,那么这里的连续吃到的次数为1.
  • 如果数字为: ...1111.... ,那么这里连续的4个1表示3次连续,也就是说只要连续,就算1次。
    期望次数,也就是说我们需要算出0个连续,1个连续,....9个连续。这10个计数。
注:这里的连续其实就是取决于当前位置的前一个位置的状态即可。因此可以用DP来解决
此题目是一个数数的问题,显然可以使用DP来进行求解。
global[i][j][k] : 表示前i个饺子中,已经吃到了j个硬币,并且连续的次数为k。
local[i][j][k] : 表示前i个饺子中,吃到了j个硬币,并且第k次连续发生在第i个位置上。(也就是说第i-1次吃到的也是饺子)。并且连续的次数为k。
  • local[i][j][k] = local[i-1][j-1][k-1] + global[i-3][j-2][k-1]

  • global[i][j][k] = local[i][j][k] + global[i-2][j][k] + global[i-2][j-1][k] + local[i-3][j-2][k-1] + global[i-3][j-1][k]

显然上式以最后一次是否连续作为子问题是不明智的,递推关系式太过复杂。

下面从另一个角度来分析:
以最后两位的状态来决定:
  • 11 : 那就是连续一次,
  • 10 , 01, 00 , 都没有连续,子问题直接递推即可。
    因此,定义如下子问题:
    f[i][j][k][0/1] : 表示前i个饺子中,吃到了j个硬币,并且有k个连续。且最后一个是0/1的次数。
    那么我们要求的就是: f[100][10][k][0] + f[100][10][k][1]; k = {1,2,3,...,9}
    注意:这里的最后一维其实就是一个0/1的记录,当然你也可以使用两个三维数组来表示。
    Python代码实现如下:
 
 
 
def c
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值