
题解引用了拉格朗日乘数,但是我不会,所以讲一个更简单的方法。
当 ppp 确定的时候,得分的期望应该是 2×∑i(pi−pi2)2\times\sum i(p_i-p_i^2)2×∑i(pi−pi2) 。令 f(p)=p−p2f(p)=p-p^2f(p)=p−p2 然后画出它的图像
设最优解为 p∗p^*p∗ ,那么任意 pa∗,pb∗p_a^*,p_b^*pa∗,pb∗ 一定满足 af′(pa∗)=bf′(pb∗)af'(p_a^*)=bf'(p_b^*)af′(pa∗)=bf′(pb∗) 。这个很好理解,假设 af′(pa∗)>bf′(pb∗)af'(p_a^*)>bf'(p_b^*)af′(pa∗)>bf′(pb∗) ,则可以让 pa∗+xp_a^*+xpa∗+x ,pb∗−x,(x→0)p_b^*-x,(x\rightarrow0)pb∗−x,(x→0) ,于是 apa∗(1−pa∗)+bpb∗(1−pb∗)<a(pa∗+x)(1−(pa∗+x))+b(pb∗−x)(1−(pb∗−x))ap_a^*(1-p_a^*)+bp_b^*(1-p_b^*)<a(p_a^*+x)(1-(p_a^*+x))+b(p_b^*-x)(1-(p_b^*-x))apa∗(1−pa∗)+bpb∗(1−pb∗)<a(pa∗+x)(1−(pa∗+x))+b(pb∗−x)(1−(pb∗−x)) 显然这样 p∗p^*p∗ 就不是最优的了。所以画出每一个 yi=if′(p)y_i=if'(p)yi=if′(p) 的图像
和图中一样,我们现在只需要找到一个蓝线 l:y=Cl:y=Cl:y=C ,使得联立 yi=if′(p)y_i=if'(p)yi=if′(p) 与 y=Cy=Cy=C 后 ∑pi=1\sum p_i=1∑pi=1 。这个问题直接二分就可以了。
这样我们就能求出 CCC,考虑如何求答案,因为 pi=i−C2ip_i=\frac{i-C}{2i}pi=2ii−C ,所以答案的可以写成 ∑i>Ci2−C22i\sum_{i>C}\frac{i}{2}-\frac{C^2}{2i}∑i>C2i−2iC2 。所以求出 CCC 后,我们可以直接计算出答案。总时间复杂度 O(Tlogn)O(T\log n)O(Tlogn) 。
写代码的时候注意精度问题,别二分进死循环了2333
#include <bits/stdc++.h>
#define N 1000006
using namespace std;
const double eps=1e-10;
const int maxn=1e6;
double n,inv[N],sum[N];
int nn;
void get_pos(double &mid){
double l=0,r=n,now;
while(r-l>eps){
mid=(r+l)*0.5;
if(mid==l||mid==r) break;
now=n-floor(mid)-mid*(inv[nn]-inv[(int)floor(mid)]);
if(now>2) l=mid;
else r=mid;
}
}
void work(){
cin>>n; nn=n;
if(n<=1){ printf("%.14lf\n",(double)0); return; }
if(n==2){ printf("%.14lf\n",(double)1.5); return; }
double pos=(n-2.0)/inv[nn],ans=0,o=0.5;
get_pos(pos);
ans=o*(sum[nn]-sum[(int)floor(pos)]-pos*pos*(inv[nn]-inv[(int)floor(pos)]));
printf("%.14lf\n",ans);
}
void init(){
for(double i=1;i<=maxn;i++)
inv[(int)i]=inv[(int)i-1]+(double)1.0/i,
sum[(int)i]=sum[(int)i-1]+i;
}
int main(){
init();
int T; cin>>T;
while(T--){ work(); }
}
听蒋神讲完题解做法后发现,我这个做法就是底层逻辑2333,(所以我前两天的拉格朗日乘子还是白学了giao
博客内容讲述了如何使用二分查找方法解决一个数学优化问题,涉及期望得分的计算。通过构造函数和图像分析,找到最优解,并给出具体步骤和代码实现,强调在实际编程中需要注意精度问题。
9053

被折叠的 条评论
为什么被折叠?



