题目链接: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;
}