HDU 4815 Little Tiger vs. Deep Monkey 2013 长春现场赛C题

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4815

【题意】

     n个题目,每题有各自的分数,A有50%的概率答对一道题目得到相应分数,B想要在至少P的概率上总分不低于A,问B至少要得到多少分。

【分析】

     最简单粗暴的做法是算出每个可能得到的总分的概率,原问题可以转化成在概率和<=P下A所有可能得到的总分集合中最大分数的最小值为多少,于是答案就是按分数排序后前k项的概率和刚好>=P。

   但是计算所有可能的概率的复杂度是O(2n),不能满足我们的需求。细心分析可以发现问题可以分离出重叠子问题f[i][j]表示前i个题目得到j分数的概率,于是类似背包问题,可以找出递推式:

           f[i][j]=f[i-1][j]*0.5                                   (score[i]>j)
           f[i][j]=f[i-1][j-score[i]]*0.5+f[i-1][j]*0.5    (score[i]<=j)

   于是问题就解决了。

【代码】

 1 //by wuminye
 2 #include <stdio.h>
 3 #include <string.h>
 4 int data[41];
 5 double dp[40001];
 6 int main()
 7 {
 8     int T;
 9     scanf("%d",&T);
10     while (T--)
11     {
12         int n,sum=0;
13         double p;
14         scanf("%d%lf",&n,&p);
15         for (int i=0;i<n;++i)
16         {
17             scanf("%d",data+i);
18             sum+=data[i];
19         }
20         memset(dp,0,(sum+1)*sizeof(double));
21         dp[0]=1;
22         for (int i=0;i<n;++i)
23             for (int j=sum;j>=0;--j)
24         {
25             if (data[i]>j) dp[j]*=0.5;
26             else dp[j]=dp[j-data[i]]*0.5+dp[j]*0.5;
27         }
28         for (int i=0;i<=sum;++i)
29         {
30             p-=dp[i];
31             if (p<=1e-6) {printf("%d\n",i); break;}
32         }
33     }
34 }
View Code

 

posted @ 2014-02-05 18:26  wuminye  阅读(526)  评论(0编辑  收藏  举报