题意:n道判断题,每题有相应的分数,一个人瞎蒙,问另一个人需要得多少分才能达到p的概率不输给他。
思路:dp(类似01背包)。dp(i,j)表示回答到第i题,分数为j分有多少种回答方法。然后根据概率的定义计算。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#include <sstream>
#define INF 1000000000
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
using namespace std;
ll s[42];
ll dp[2][40010];
ll pre[40010];
int main(){
int t;
cin>>t;
while(t--){
memset(dp,0,sizeof(dp));
int n;
double p;
cin>>n>>p;
for(int i=1;i<=n;i++){
scanf("%I64d",&s[i]);
}
dp[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=40000;j++){
dp[i%2][j]=dp[(i-1)%2][j];
if(j-s[i]>=0){
dp[i%2][j]+=dp[(i-1)%2][j-s[i]];
}
}
}
pre[0]=dp[n%2][0];
for(int i=1;i<=40000;i++){
pre[i]=pre[i-1]+dp[n%2][i];
}
int ans=-1;
for(int i=0;i<=40000;i++){
double test=(pre[i]+0.0)/(pre[40000]+0.0);
if(test>p-0.000000001){
ans=i;break;
}
}
cout<<ans<<endl;
}
return 0;
}