这个题告诉我们两点:
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; }