题意: n个题目,每个题目答对或打错, 分数一个有2^n种可能, 求最小的数x, 使得这些可能的数中 x what score should I get at least so that I will not lose in the contest with probability of at least P?
背包处理所有情况,二分查找x即可 。
typedef long long LL ;
int x[48] ;
LL dp[40008] ;
int num[40008] ;
LL cnt[40008] ;
int main(){
double p ;
int sum , n , i , j , k , t ;
cin>>t ;
while(t--){
scanf("%d%lf" , &n , &p) ;
sum = 0 ;
for(i = 1 ; i <= n ; i++){
scanf("%d" , &x[i]) ;
sum += x[i] ;
}
memset(dp , 0 , sizeof(dp)) ;
dp[0] = 1 ;
for(i = 1 ; i <= n ; i++){
for(j = sum ; j >= x[i] ; j--){
if(dp[j - x[i]]) dp[j] += dp[j-x[i]] ;
}
}
k = 0 ;
for(i = 0 ; i <= sum ; i++){
if(dp[i] == 0) continue ;
k++ ;
num[k] = i ;
cnt[k] = dp[i] ;
}
double all = pow(2.0 , n) , s ;
int L = 0 , R = sum , M , ans ;
while(L <= R){
M = (L + R) >> 1 ;
s = 0 ;
for(i = 1 ; i <= k ; i++){
if(num[i] > M) break ;
s += cnt[i] ;
}
if(s >= p * all){
ans = M ;
R = M-1 ;
}
else L = M+1 ;
}
printf("%d\n" , ans) ;
}
return 0 ;
}