题目大意:Roy要抢劫银行,每抢一个银行都有一定的被抓概率,现在给你一个安全概率,以及每个银行的库存现金和抢劫该银行被抓的概率,问你在安全概率的情况下Roy最多可以抢劫多少现金。
乍一看是背包问题,其实就是背包问题,只要稍微变形一下就行了,可以看出,本题中安全概率是背包的容量,每个银行的被抓概率是质量,但这样肯定是行不通的,因为我们要用dp[ i ]数组来纪录质量为i时的最大价值,那么质量显然要为整数才行,所以我们可以把问题反过来看,把每个银行的库存现金看做是质量,那么所有银行的库存现金总数就是背包的容量了,每个银行被抓的概率就可以看做是每件物品的价值了,这样问题便迎刃而解了。
状态转移方程:dp(i,sum)=max(dp(i-1,sum),dp(i-1,sum-w[ i ])*(1-p[ i ] ));
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef struct node
{
int m;
double p;
}Bag;
Bag bag[110];
double dp[11000];
int main()
{
int t,n,sum;
int i,j;
double pro;
cin>>t;
while(t--)
{
sum=0;
scanf("%lf%d",&pro,&n);
for(i=1;i<=n;i++)
{
scanf("%d%lf",&bag[i].m,&bag[i].p);
sum+=bag[i].m;
}
memset(dp,0,sizeof(dp));
dp[0]=1;
for(i=1;i<=n;i++)
for(j=sum;j>=bag[i].m;j--)
dp[j]=max(dp[j],dp[j-bag[i].m]*(1-bag[i].p));
for(i=sum;i>=0;i--)
if(dp[i]>1-pro)
{
printf("%d\n",i);
break;
}
}
return 0;
}