这个题告诉我们两点:

1)求概率,正向不好求,考虑反面

2)0,1背包的容量和dp值是可以互换的,数据类型和范围帮助我们确定

#include<bits/stdc++.h>
using namespace std;
const int N=105;
double p[N];
int m[N];
int n;
double P;
double dp[N*N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int up=0;
        scanf("%lf%d",&P,&n);
        for(int i=0;i<n;i++){
            scanf("%d%lf",&m[i],&p[i]);
            up+=m[i];
        }
        //求概率问题,如果正向不好处理,考虑求问题的补问题
        memset(dp,0,sizeof(dp));
        dp[0]=1;//dp[i]表示抢到的钱等于i的时候逃跑最大的概率。
        for(int i=n-1;i>=0;i--){
            for(int j=up;j>=m[i];j--){
                dp[j]=max(dp[j],dp[j-m[i]]*(1-p[i]));
            }
        }
        for(int i=up;i>=0;i--){
            if(dp[i]>1-P){
                printf("%d\n",i);
                break;
            }
        }
    }
    return 0;
}
02-01 09:28