hdu———2955”Robberies”

来源:互联网 发布:tcpdump 端口 抓包 编辑:程序博客网 时间:2024/06/06 00:34

题目描述:题目描述

基本思路:

该题也是一道背包题,用了背包的思想,但是多转了一道弯。很显然,将概率作为背包容量,所偷得的钱作为value是无法实现的。我们可以转换一下,将所偷得的钱作为背包容量,不被抓住的概率作为value,所以总结一下:我们只需要求出各个银行的钱组合下的不被抓的最大概率值,然后循环求出偷得最大钱数且不被抓。(这里有一个要注意:举个例子,如果给出数据1,0.1;2,0.2;3,0.3;那么当钱数为4时(1,2,3不能组合出4),不被抓的概率显然需要为0,因为如果它为非0是没有意义的。)

代码实现:

#include <iostream>#include <cstring>#include <cstdio>using namespace std;int T;double data_p[102];int data_v[102];double f[10005];int main(){    scanf("%d",&T);    while(T--)    {        double sum;        int num,val_p=0;        scanf("%lf%d",&sum,&num);        for(int i=1;i<=num;i++)        {            scanf("%d%lf",&data_v[i],&data_p[i]);            val_p+=data_v[i];        }        memset(f,0,sizeof(f));        f[0]=1;        for(int i=1;i<=num;i++)            for(int j=val_p;j>=data_v[i];j--)            if(f[j]<f[j-data_v[i]]*(1-data_p[i]))                f[j]=f[j-data_v[i]]*(1-data_p[i]);                else f[i]=f[i];        /*for(int i=1;i<=num;i++)            for(int j=data_v[i];j<=val_p;j++)            if(f[j]<f[j-data_v[i]]*(1-data_p[i]))            f[j]=f[j-data_v[i]]*(1-data_p[i]);*/        for(int i=val_p;i>=0;i--)        {            cout<<"i is:"<<i<<"  f[i] is :  "<<f[i]<<endl;            if(f[i]-1+sum>0.000000001)        {            printf("%d\n",i);            break;        }        }    }    return 0;}

如果将背包实现的部分写成:

for(int i=1;i<=num;i++)            for(int j=data_v[i];j<=val_p;j++)            if(f[j]<f[j-data_v[i]]*(1-data_p[i]))            f[j]=f[j-data_v[i]]*(1-data_p[i]);
就是错的,因为前面讲过了,f[4]为一个非零值是没有意义的,而且会导致错误。


原创粉丝点击