杭电多校第10场

c题: hdu6693

题意:给出n个买当前物品令人开心的概率值,问从中买1-n个,从购买的全部中选出一个使其开心的最大概率值。

题意很好理解,首先我们从什么入手,我们该怎么想这种题目,首先可以明确的一点是可以选一个,或者选两个,或者选3个,4个,。。。。n个的。

大的情况可以从小的情况中推理出来 ,

1:  首先如果选一个的话那么直接就选择最大的就可以了?

2:  如果选择两个,  不妨设置  pi<pj     则有  pi*(1-pj)+pj*(1-pi)  这是只开心一次的期望   那么就有  pi+pj-2*pi*pj  要选择两个,肯定是他能要变大才会选择。。。。

即  pi+pj-2*pi*pj> pj    有   pi -2*pi*pj >0    得到  pi*(1-2*pj) >0   得到pj<0.5   同理选3个,选4个的时候也要满足一下这样的原则。。。。。

3:  那选择多个的话怎么选择呢。这样选择的话很显然的话可以从两个看出,   设置pi<pk<pj<0.5   则有  pi*(1-pj) +pj*(1-pi)  =pi+pj-2*pi*pj     有  pk+pj-2*pk*pj

则有   pk+pj-2*pk*pj  -pi -pj  +2*pi*pj    =   pk-pi  -2pj(pk-pi)=(pk-pi)(1-2pj) >0   这样就说明选择越大的越好。。。。。。。。。

4:然后显然可以得到一个算法,先排好序,选择一个最大的,然后找到<=0.5的数的位置,从这个位置开始往前找,选一个,选两个,选3个,直到选完全部的时候即可。。。。。。。。。。

5: 然后这个列出一下公式保存一下即可,下面是代码。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <bitset>
 6 #include <iostream>
 7 typedef long long ll;
 8 using namespace std;
 9 const int maxn=10200;
10 int t,n;
11 double pi[maxn];
12 int main(){
13     scanf("%d",&t);
14     while(t--){
15         scanf("%d",&n);
16         for(int i=1;i<=n;i++) scanf("%lf",&pi[i]);
17         sort(pi+1,pi+n+1);
18         int tip=0;
19         for(int i=1;i<=n;i++){
20             if(pi[i]<=0.5){
21                 tip=i;
22             }
23         }
24         if(tip==0) printf("%.10lf\n",pi[n]);
25         else{
26             double ans=pi[n];
27             double p1=1.00-pi[tip],p2=pi[tip];
28             for(int i=tip-1;i>=1;i--){
29                 ans=max(ans,pi[i]*p1+(1-pi[i])*p2);
30                 p2=pi[i]*p1+(1-pi[i])*p2;
31                 p1=p1*(1-pi[i]);
32             }
33             printf("%.10lf\n",ans);
34         }
35     }
36     return 0;
37 }
View Code

猜你喜欢

转载自www.cnblogs.com/pandaking/p/11516911.html