题目大意:有个人想抢银行,然后他找出了各个银行能被抢的最大金额和被抓的概率,他希望在不高于P的被抓概率下尽可能抢到最多的金额。
分析: 这题是01背包问题,因为是概率问题,所以在这个用反面考虑会比较方便。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 200
double dp[10005];
int main() {
int t;
scanf("%d",&t);
while(t--){
int n,m[maxn],sum=0;
memset(dp,0,sizeof(dp));
dp[0]=1;
double P,p[maxn];
scanf("%lf%d",&P,&n);
P=(1-P);//反面考虑不被抓的概率 ,简化问题。
for(int i=0;i<n;i++){
scanf("%d%lf",&m[i],&p[i]);
p[i]=1-p[i];
sum+=m[i];
}
for(int i=0;i<n;i++){
for(int j=sum;j>=m[i];j--){
dp[j]=max(dp[j],dp[j-m[i]]*p[i]);
}
}
for(int j=sum;j>=0;j--){
if(dp[j]>=P)
{
printf("%d\n",j);//递减找出大于不被抓的概率的最大财富值
break;
}
}
}
return 0;
}