简单的背包问题,需要转化
首先求得所有银行的钱的总和sum,dp[j]表示抢j个钱的最大安全概率,money[i]表示第i个银行的钱,prob[i]表示在第i个银行被抓的概率
然后可以列出状态转移方程:dp[j]=max(dp[j], dp[j-money[i])*(1-prob[i]))
其中,j的范围是0到sum,初始化时dp[0]=1,其余均为-1
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define REP(i,n) FOR(i,0,n-1)
int main()
{
int T;
float p;
int n;
int money[110];
float prob[110];
float dp[10010];
cin>>T;
while(T--){
scanf("%f%d",&p,&n);
int sum = 0;
REP(i,n) {
scanf("%d%f",money+i,prob+i);
sum += money[i];
}
FOR(i,1,sum) dp[i]=-1;
dp[0]=1;
REP(i,n){
for(int j=sum; j>=money[i]; j--){
dp[j]=max(dp[j],dp[j-money[i]]*(1-prob[i]));
}
}
//FOR(i,0,sum) cout<<dp[i]<<" ";cout<<endl;
for(int i=sum; i>=0; i--)
if(dp[i] > 1-p){
printf("%d\n",i);
break;
}
}
}