Robberies(背包01)

题目链接: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值