Robberies(HDU

来源:互联网 发布:淘宝培训课 编辑:程序博客网 时间:2024/05/22 09:38

分析:01背包问题,但是该题很容易会用概率作为背包容量,这是不对的,概率是浮点数,则需扩大背包容量,则背包容量是钱数,银行总钱数就是背包最大容量,dp[i] 代表钱数为i时的成功逃跑概率(即不被抓到),成功逃跑就是没有被任何银行抓到,若被一个银行抓到就不算成功逃跑,则成功逃跑概率p = (1-p1)(1-p2)(1-p3) ,p1,p2,p3是每个银行被抓到的概率,最后按照钱数从大到小遍历一遍,找到满足条件的最大钱数。
代码如下:

#include <iostream>#include<cstring>#include<cstdio>#include<vector>#include<algorithm>#define INF 0x3f3f3f3fusing namespace std;const int maxn=100+20;int m[maxn];double p[maxn],dp[maxn*maxn];int main(){    int T;    scanf("%d",&T);    while(T--)    {        memset(dp,0,sizeof(dp));        double p0;        int n;        scanf("%lf%d",&p0,&n);        int sum=0;      //sum求背包容量最大值        for(int i=0;i<n;i++)        {             scanf("%d%lf",&m[i],&p[i]);             sum+=m[i];        }        dp[0]=1;      //抢不到任何钱时逃跑概率为1        for(int i=0;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\n",i);                break;            }        }    }}