题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955
题目大意:小偷去银行偷钱,每个银行给出能被偷的钱数和小偷在此银行会被抓的概率。
算出小偷不会被抓时能偷到的钱。给出小偷会被抓的概率R,在银行被抓的总概率不能超过此概率。
题解:以能偷到的钱为背包容量,以不会被抓的概率为物品价值,需要注意背包恰好装满,
而且概率是用乘法,给出的测试数据有点坑。标准01背包。输出物品价值超过不会被抓概率(1-R)时的背包容量.注意偷不到钱时被抓概率为0.
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
double dp[10005];
int main(){
int t;
scanf("%d",&t);
while(t--){
for(int i=1;i<=10000;i++){
dp[i]=0;
}
dp[0]=1;
double p;
int n,sum=0;
scanf("%lf%d",&p,&n);
p=1-p;
int a[n];
double b[n];
for(int i=0;i<n;i++){
scanf("%d%lf",&a[i],&b[i]);
sum+=a[i];
b[i]=1-b[i];
}
for(int i=0;i<n;i++){
for(int j=sum;j>=a[i];j--){
if(dp[j-a[i]]!=0)
dp[j]=max(dp[j],dp[j-a[i]]*b[i]);
else if(j==a[i])
dp[j]=b[i];
}
}
for(int i=sum;i>=0;i--){
if(dp[i]>=p){
printf("%d\n",i);
break;
}
}
}
}