题解:P11918 [PA 2025] 考试 / Egzamin
背景知识请先阅读 https://www.luogu.com.cn/article/xs2uucwg
有
n 个随机变量X_1,X_2,\ldots,X_n ,其中X_i 有p_i 的概率为1 ,否则为-1 。你选择一个k ,再选择其中的k 个随机变量,求最优决策下你选择的随机变量的和\ge t 的概率。
首先,可以贪心地选随机变量,因为希望和尽可能大,所以优先选
将所有
可以设计一个简单的 DP,记
每一次和只会
这样做是
考虑优化,令
转移时只需舍去
下面给出这个做法的复杂度证明。
考虑对于每一个
容易注意到的是,满足
代入
不等式两边同时取对数的相反数:
解二次不等式组得:
舍去常数,由于
取等号时最优,得到满足条件的区间为
综上,总时间复杂度为
经过测试,实际
核心代码:
constexpr int N=5e4+5;
constexpr double eps=1e-11;
namespace Junounly
{
int n,K;
double p[N];
vector<pair<int,double> > q[2];
void main()
{
scanf("%d%d",&n,&K);
for(int i=1;i<=n;i++) scanf("%lf",&p[i]);
sort(p+1,p+n+1,greater<double>());
q[0].emplace_back(0,1);
double res=0;
for(int i=1,op=0;i<=n;i++,op^=1)
{
for(auto [X,Y]:q[op])
{
int x=X-1;double y=Y*(1-p[i]);
if(y>eps)
{
if(q[op^1].size()&&q[op^1][q[op^1].size()-1].first==x) q[op^1][q[op^1].size()-1].second+=y;
else if(q[op^1].size()>1&&q[op^1][q[op^1].size()-2].first==x) q[op^1][q[op^1].size()-2].second+=y;
else q[op^1].emplace_back(x,y);
}
x=X+1;y=Y*p[i];
if(y>eps) q[op^1].emplace_back(x,y);
}
q[op].clear();
double now=0;
for(auto [X,Y]:q[op^1])
if(X>=K) now+=Y;
res=max(res,now);
}
printf("%.11lf\n",res);
}
}