刚开始一直以为概率最低为0.01,就乘以一百变成整数,化为纯的01背包问题求解。结果果不其然wa了。
想了一会儿,可以将金钱看成重量,将所有金钱加起来几位最大重量。可以定义dp[i]为:装满容量为i的背包的最小概率。
就有状态转移方程:dp[i]=max(dp[i],dp[i-bag[i].v]*bag[i].p。
这里我将概率转成了不被抓的概率。
#include<iostream>
#include<cstdio>
using namespace std;
const int N=105;
const int maxv=10005;
double dp[maxv];
struct node
{
int v;
double p;
}bag[N];
double m;
int n;
double max(double a,double b)
{
if(a>b) return a;
return b;
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
cin>>t;
while(t--)
{
fill(dp,dp+maxv,0);
cin>>m>>n;
int sum=0;
for(int i=0;i<n;i++)
{
cin>>bag[i].v>>bag[i].p;
bag[i].p=1-bag[i].p;
sum+=bag[i].v;
}
dp[0]=1;
for(int i=0;i<n;i++)
{
for(int j=sum;j>=bag[i].v;j--)
dp[j]=max(dp[j],dp[j-bag[i].v]*bag[i].p);
}
for(int i=sum;i>=0;i--)
if(dp[i]>1-m)
{
cout<<i<<endl;
break;
}
}
return 0;
}