hdu2955_01背包

来源:互联网 发布:数据挖掘r语言实战 编辑:程序博客网 时间:2024/06/15 12:28

这个题 背包的容量不能是概率,因为是小数
所以把money看做背包的体积,把概率看做是物品的价值
当dp[i][j]表示抢前i个bank,抢j数量的money时 能不被抓的概率
dp[i][j]=max(dp[i-1][j],dp[i-1][j-money[i]](1-p[i]))
不抢第i个bank 或者 抢第i个bank


坑点 b[i]中存储的是 被抓的概率 v也是被抓的概率
如果bank1 被抓概率p1, bank2 被抓概率p2
那么抢bank1和bank2
不被抓的概率是 (1-p1)*(1-p2)
被抓的概率 p1+p2-p1*p2

#include <stdio.h>#include <string.h>int t,n,sum,a[105];double v,b[105],dp[10005];double max(double a,double b){    if(a>b) return a;    return b;}double min(double a,double b){    if(a>b) return b;    return a;}int main(){    scanf("%d",&t);    while(t--){        scanf("%lf %d",&v,&n);        int i,j;        sum=0;        for(i=1;i<=n;i++){            scanf("%d %lf",&a[i],&b[i]);            sum+=a[i];        }        for(i=1;i<=sum;i++) dp[i]=0;        dp[0]=1;//dp中是逃跑的概率 越大越好         for(i=1;i<=n;i++){            for(j=sum;j>=a[i];j--){             }        }        for(j=sum;j>=0;j--){ //有可能一分钱抢不到 所以j要可以到0             if(dp[j]>1-v){                printf("%d\n",j);                break;            }        }        //下面的代码 dp中是被抓的概率         for(i=1;i<=sum;i++) dp[i]=1;        dp[0]=0;        for(i=1;i<=n;i++){            for(j=sum;j>=a[i];j--){                dp[j]=min(dp[j],dp[j-a[i]]+b[i]-dp[j-a[i]]*b[i]);            }        }         for(j=sum;j>=0;j--){            if(dp[j]<v) {                printf("%d\n",j);break;            }        }    }}