Robberies(背包01)

来源:互联网 发布:iphone检测软件 编辑:程序博客网 时间:2024/05/17 05:50
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955题目含义:一个抢劫犯去抢银行,第一行输入的小数是代表被抓的概率x,整数y代表的是有几个银行,以下的y行是每个银行的被抓的概率n和每个银行里面有多少钱m,要求在不抓住的情况下求出能得到最多的钱;有二个思路,x当作背包的容量,每个银行的被抓概率是每个物品的重量,m就是其价值,但是这样做下来发现不能遍历所有的,因为每个银行的被抓概率不是2位小数,会更小,所以只能换个思路;第二个思路的区别在于:第一个思路的每个银行的被抓概率是每个去抢的银行的概率之和,只要小于x就是不会被抓的,而求不被抓率的话等于每个去抢的银行的不被抓概率之乘积,只要所抢的银行所有的不被抓率乘积小于1-x就是可以的,相当与所抢的钱是背包的容量,概率是价值;

以下是代码:

#include<stdio.h>#include<string.h>double max(double x,double y){    return x>y?x:y;}int main(){    int n;    scanf("%d",&n);    double  w[10005];    int val[10005];    double dp[10005];    while(n--)    {        double x,x1;        int y;        scanf("%lf%d",&x,&y);        x1=1-x;        memset(val,0,sizeof(val));        memset(w,0,sizeof(w));        memset(dp,0,sizeof(dp));        dp[0]=1;        int sum=0;        for(int i=1;i<=y;i++)        {            double z;            scanf("%d%lf",&val[i],&z);              w[i]=1-z;            sum=sum+val[i];        }           for(int i=1;i<=y;i++)            for(int j=sum;j>=val[i];j--)                dp[j]=max(dp[j-val[i]]*w[i],dp[j]);        for(int i=sum;i>=0;i--)        if(dp[i]>=x1)        {            printf("%d\n",i);            break;        }    }       return 0;}
原创粉丝点击