这道背包题和我们常见的背包题有所不同。如果根据以前做背包的惯性思维和题中数据的迷惑,会把概率乘以100来当作容量。但是经测试是不行的。
我们不妨换种思路,看做DAG上的DP思想。将所有有可能达到的钱的最大“逃跑”概率算出来,最后再将能够达到的最大的钱输出。而能不能够达到这个可以将所有除0以外的值初始化为0.意为逃跑的概率为0。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
//freopen("data.in","r",stdin);
double dp[10005];
int sum,n,t;
double p,v[105];
int c[105];
int i,j,ret;
scanf("%d",&t);
while(t--)
{
sum=0;
scanf("%lf%d",&p,&n);
for(i=0;i<n;i++)
scanf("%d%lf",&c[i],&v[i]);
for(i=0;i<n;i++)
sum+=c[i];
for(i=0;i<n;i++) v[i]=1-v[i];
dp[0]=1;
for(i=1;i<=sum;i++) dp[i]=0;
for(i=0;i<n;i++)
for(j=sum;j>=c[i];j--)
{
if(dp[j]<=dp[j-c[i]]*v[i])
{
dp[j]=dp[j-c[i]]*v[i];
}
}
ret=-1;
for(i=0;i<=sum;i++)
if(dp[i]>=(1-p)) ret=i;
printf("%d
",ret);
}
return 0;
}