Robberies HDU - 2955(dp)

博客围绕银行抢劫问题展开,给定n个银行,每个有被抓概率和可抢金额,还有最大安全概率。最初尝试用背包问题思路,因概率是浮点数遇问题。正确思路是用动态规划,dp[i]表示抢到i钱时不被抓的最大概率,给出dp公式及答案计算方式。

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

题意:你去抢银行,给你n个银行,每个银行有被抓的概率和能抢到的钱,给你一个最大的概率,当你被抓的总概率小于这个概率时可以认为你是安全的。。问你在安全的情况下能抢的最多的钱是多少。

题解:刚开始想成最简单的背包问题,因为体积(概率)是浮点数,所以疯狂将概率*100,*1000.等等来直接计算,发现不行。题目的思路是dp[i] = x; i 为抢到的钱,x为不被抓的最大概率。(我因为没有仔细理解题目,以为抢了2个银行是将2个银行的概率加起来就是你被抓的概率,而且这种思路还能过样例所以疯狂wa。)

dp公式为dp[j + w[i]] = max(dp[j + w[i]], dp[j] * (1 - s[i]));答案为 if(1 - dp[j + w[i]] <= v) maxx = max(maxx, j + w[i]);

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 5;
double s[maxn];
int w[maxn];
double dp[20005];
int main()
{
//    freopen("in.txt", "r", stdin);
    int T;
    cin >> T;
    while(T--)
    {
        int n;
        double v;
        cin >> v >> n;
        int sum = 0;
        for(int i = 1; i <= n; i++)
        {
            cin >> w[i] >> s[i];
            sum += w[i];
        }
        memset(dp, 0, sizeof(dp));
        dp[0] = 1;
        int maxx = 0;
        for(int i = 1; i <= n; i++)
            for(int j = sum - w[i]; j >= 0; j--)
            {
                if(j == 0 || dp[j])
                {
                    dp[j + w[i]] = max(dp[j + w[i]], dp[j] * (1 - s[i]));
                    if(1 - dp[j + w[i]] <= v) maxx = max(maxx, j + w[i]);
                }
            }
        printf("%d\n", maxx);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值