分析:01背包问题,但是该题很容易会用概率作为背包容量,这是不对的,概率是浮点数,则需扩大背包容量,则背包容量是钱数,银行总钱数就是背包最大容量,dp[i] 代表钱数为i时的成功逃跑概率(即不被抓到),成功逃跑就是没有被任何银行抓到,若被一个银行抓到就不算成功逃跑,则成功逃跑概率p = (1-p1)(1-p2)(1-p3) ,p1,p2,p3是每个银行被抓到的概率,最后按照钱数从大到小遍历一遍,找到满足条件的最大钱数。
代码如下:
#include <iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=100+20;
int m[maxn];
double p[maxn],dp[maxn*maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(dp,0,sizeof(dp));
double p0;
int n;
scanf("%lf%d",&p0,&n);
int sum=0; //sum求背包容量最大值
for(int i=0;i<n;i++)
{
scanf("%d%lf",&m[i],&p[i]);
sum+=m[i];
}
dp[0]=1; //抢不到任何钱时逃跑概率为1
for(int i=0;i<n;i++)
{
for(int j=sum;j>=m[i];j--)
dp[j]=max(dp[j],dp[j-m[i]]*(1-p[i]));
}
for(int i=sum;i>=0;i--) //按照钱数从大到小遍历
{
if(dp[i]>(1-p0))
{
printf("%d\n",i);
break;
}
}
}
}