01背包(小偷的概率)
发布日期:2021-05-15 00:45:53 浏览次数:9 分类:精选文章

本文共 1653 字,大约阅读时间需要 5 分钟。

为了解决这个问题,我们需要找到一种方法来计算Roy抢取银行时的最大收益,同时确保逃脱的概率不超过给定的阈值。这个问题类似于0-1背包问题,但带有概率约束。因此,我们需要使用动态规划来解决这个问题。

方法思路

  • 问题分析:Roy可以选择抢取每个银行的钱,但每个银行抢取会带来一个成功概率Pj,我们需要确保所有抢取动作的成功概率不超过给定的阈值P。
  • 动态规划的状态转移:我们使用一个数组dp,其中dp[i]表示抢取i元的成功概率。初始化时,dp[0] = 1.0,因为没有抢取任何银行时的成功概率是1。
  • 更新规则:对于每个银行,考虑是否抢取该银行,更新dp数组。抢取银行j会增加Mj元,且成功概率变为当前概率乘以(1 - Pj)。
  • 寻找最大值:处理完所有银行后,从dp数组中找到最大的i,使得dp[i] <= P。
  • 解决代码

    def main():    import sys    input = sys.stdin.read    data = input().split()    idx = 0    T = int(data[idx])    idx += 1    for _ in range(T):        P = float(data[idx])        N = int(data[idx+1])        idx +=2        v = []        w = []        sumM = 0        for _ in range(N):            M = int(data[idx])            P_b = float(data[idx+1])            v.append(M)            w.append(P_b)            sumM += M            idx +=2                MAX = sumM        dp = [0.0]*(MAX +1)        dp[0] = 1.0        for j in range(MAX +1):            if dp[j] ==0:                continue            for i in range(j, -1, -1):                if i ==j:                    idx_j = j + v[i]                    if idx_j > MAX:                        continue                    prob = dp[i] * (1 - w[i])                    if prob > dp[idx_j]:                        dp[idx_j] = prob                for i in range(MAX, -1, -1):            if dp[i] <= P and dp[i] >=0:                print(i)                break    if __name__ == "__main__":    main()

    代码解释

    • 输入处理:读取输入数据并解析。每个测试用例包含一个阈值P和N个银行的信息。
    • 动态规划数组初始化:初始化dp数组,其中dp[0] = 1.0表示没有抢取任何银行时的成功概率。其他位置初始化为0。
    • 状态转移:对于每个银行,更新dp数组。从当前最大金额向下遍历,计算抢取该银行后的概率更新。
    • 查找最大值:从最大金额开始向下查找,找到第一个满足dp[i] <= P的值,这就是 Roy可以得到的最大金额。

    这种方法确保了我们能计算出在不超过给定概率约束下,Roy能获取的最大金额。

    上一篇:并查集(小西的迷宫)
    下一篇:01背包(食堂)

    发表评论

    最新留言

    做的很好,不错不错
    [***.243.131.199]2025年04月12日 01时31分54秒