题意:
有许多物品,每个物品有一定概率让女朋友开心。你想让女朋友开心且只开心一次,让你挑一些物品,使得这个只开心一次的概率最大,求最大概率。
题解:
设物品i让女朋友开心的概率为$p_i$
若你挑选了1-k共k个物品,则可记女朋友一次都开心不了的概率$w_0=prod _{i=1}^k (1-p_i)$ 女朋友恰好开心一次的概率$w_1=C_k^1sum _{i=1}^k frac{w*p_i}{1-p_i}$
则若挑第k+1个物品,女朋友恰好开心一次的概率为$w^,=w_0*p_k+w_1*(1-p_k)$
贪心选择性质:通过公式看出,若前k个物品的选择不是最优解,则第k+1个物品不管怎么选也一定不是最优解。
最优子结构性质:依旧通过公式看出,最优解一定包含概率最大的物品。
因此排序后从大到小,用上述公式贪心计算即可。
#include<iostream> #include<cmath> #include<algorithm> using namespace std; double a[100005]; //int main1(){ // int n; // while(1){ // scanf("%d",&n); // double frac=1; // double ans=0; // for(int i=1;i<=n;i++){ // scanf("%lf",&a[i]); // frac*=(1-a[i]); // } // for(int i=1;i<=n;i++){ // ans+=(frac/(1-a[i]))*a[i]; // } // printf("%f ",ans); // } // // //} int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lf",&a[i]); } sort(a+1,a+1+n); double pow=1; double ans=0; double maxx=0; for(int i=n;i>=1;i--){ double now=a[i]*pow+(1-a[i])*ans; // printf("%lf ",now); ans=now; maxx=max(maxx,now); pow*=(1-a[i]); } printf("%.8f ",maxx); } return 0; }