题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955
因为被抓的概率是实数,而背包问题中,用于做下标的必须是整数,所以此处用所有银行的总金额做下标,将逃脱率(1-pj)作为dp的值
初始化的时候,dp[0]=1(不抢的逃脱率为1);其它都为0,按照0/1背包来做即可。
AC代码:
/*HDOJ2955 作者:陈佳润 2013-04-19 */ #include<stdio.h> #include<string.h> #define max(a,b) (a>b?a:b) double pj[105];//每个银行的逃脱率 int mj[105];//每个银行的金额 double dp[10005]; int sum;//所有银行的总金额 void ZeroOnePack(double value,int weight){ int i; for(i=sum;i>=weight;i--){ dp[i]=max(dp[i],dp[i-weight]*value); } } int main(){ int Time,n,i; double P; //freopen("1.txt","r",stdin); scanf("%d",&Time); while(Time--){ scanf("%lf%d",&P,&n); sum=0; for(i=1;i<=n;i++){ scanf("%d%lf",&mj[i],&pj[i]); pj[i]=1-pj[i]; sum+=mj[i]; } //初始化 memset(dp,0,sizeof(dp)); dp[0]=1; //0/1背包 for(i=1;i<=n;i++) ZeroOnePack(pj[i],mj[i]); //找出满足逃跑概率的最大收获 for(i=sum;i>=0;i--){ if(dp[i]>1-P){ printf("%d\n",i); break; } } } return 0; }