hdu2955 — Robberies (01背包)

本博客探讨了在给定概率限制下,如何利用动态规划算法优化抢劫银行的策略,以最大化可获得的金钱数量。通过分析案例,解释了如何通过状态转移方程来确定最优解。

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

题目大意:Roy去抢银行,问在给定的被抓住的概率下,Roy可以抢的金钱数额最多,且小于给定概率

输入:第一行输入一个整数 T,为案例数,每组案例第一行输入给定概率 P 和银行数目 N,接下来 N 行输入该银行的钱数 Mj 和被抓概率 Pj


思路分析:值得注意的一点是,要将可得金钱数目当作价值,将每个银行的金钱数当作花费,状态转移方程为 dp [ j ] = max ( dp [ j ] , dp [ j - Mi ] * ( 1 - Pi )  ),其中 dp [ j ] 表示在当前容量j 下,Roy不被抓到的概率最大 && Roy可以抢到的最大钱数 (不被抓到的概率最大==被抓到的概率最小),还有一点需要注意的是,因为计算概率时是用乘法,所以 dp [ 0 ] =1.0 ,  dp [ i ] = 0 ( i = 1 , 2 , 3 ......)    

抢 n 个银行不被抓到的概率计算公式为  (1 - P0 )* ( 1 - P1 ) * ...... *( 1 - Pn ) 。 


#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=105;
int money[maxn];
double pro[maxn];
double dp[10005];

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        double p;
        int n,sum=0,i;
        cin>>p>>n;
        for(i=1;i<=n;i++)
        {
            cin>>money[i]>>pro[i];
            sum+=money[i];
            pro[i]=1-pro[i];
        }
        p=1-p;
        dp[0]=1.0;
        for(i=1;i<=n;i++)
        {
            for(int j=sum;j>=money[i];j--)
                dp[j]=max(dp[j],dp[j-money[i]]*pro[i]);
        }
        for(i=sum;i>0;i--)
            if(dp[i]>p)
                break;
        cout<<i<<endl;
    }
    return 0;
}

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值