HDU 2955_Robberies 小偷抢银行【01背包】

<题目链接>

题意:

先是给出几组数据,每组数据第一行是总被抓概率p(最后求得的总概率必须小于他,否则被抓),然后是想抢的银行数n。然后n行,每行分别是该银行能抢的钱数m[i]和被抓的概率p[i],求最大逃跑概率。被抓的概率越大,逃跑概率越小。

解题思路:

由于被抓的概率不好求,所以我们将其转化为逃跑概率,又因为逃跑概率不是简单的相加,所以这里将强的钱数作为01背包的体积,逃跑概率作为价值,求得在一定抢钱数下,最大的逃跑概率。

#include <bits/stdc++.h>
using namespace std;

int n,m[110];
double p0,p[110],dp[int(1e4+5)];

int main(){
    int T;scanf("%d",&T);while(T--){
        int sum=0;
        scanf("%lf%d",&p0,&n);
        for(int i=1;i<=n;i++)
            scanf("%d%lf",&m[i],&p[i]),sum+=m[i];
        memset(dp,0,sizeof(dp));
        dp[0]=1;    //抢钱数为0,逃跑概率为1
        for(int i=1;i<=n;i++)
            for(int j=sum;j>=m[i];j--)
                dp[j]=max(dp[j],dp[j-m[i]]*(1-p[i]));      //得到抢一定数量钱的最大逃跑概率
        for(int i=sum;i>=0;i--){
            if(dp[i]>(1-p0)){ printf("%d
",i); break; }    //输出能够成功逃跑的最大抢钱数
        }
    }
}
原文地址:https://www.cnblogs.com/00isok/p/8972560.html