hdu 4815

题意:  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  ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值