#include<bits/stdc++.h>
using namespace std;
int n,a,b,numa[50001],numb[50001];
const double eps=1e-10;
double dp[5001],p[5001],q[5001];
void check2(double va,double vb){
for(int i=1;i<=n;++i){
dp[i]=dp[i-1];numa[i]=numa[i-1];numb[i]=numb[i-1];
if(dp[i]<dp[i-1]+p[i]-va-eps){
dp[i]=dp[i-1]+p[i]-va;
numa[i]=numa[i-1]+1;numb[i]=numb[i-1];
}
if(dp[i]<dp[i-1]+q[i]-vb-eps){
dp[i]=dp[i-1]+q[i]-vb;
numa[i]=numa[i-1];numb[i]=numb[i-1]+1;
}
if(dp[i]<dp[i-1]+q[i]+p[i]-va-vb-eps-p[i]*q[i]){
dp[i]=dp[i-1]+q[i]+p[i]-q[i]*p[i]-va-vb;
numa[i]=numa[i-1]+1;numb[i]=numb[i-1]+1;
}
}
}
double check(double v1){
double l=0,r=1,mid;
int G=50;
while(G--){
mid=(l+r)/2;
check2(v1,mid);
if(numb[n]>b)l=mid;
else r=mid;
}
return l;//
}
int main(){
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;++i)scanf("%lf",&p[i]);
for(int i=1;i<=n;++i)scanf("%lf",&q[i]);
double l=0,r=1,v;
int H=50;
while(H--){
double mid=(l+r)/2;
v=check(mid);
if(numa[n]>a)l=mid;
else r=mid;
}
check2(l,v);//
printf("%.5lf\n",dp[n]+l*a+v*b);//
return 0;
}
蒟蒻想问下,其中 check函数为什么返回的是 l 而不是r,l 不是使得numb[n]>n的最小的 mid (不符合要求)吗?以及 main 函数中的二分,为什么最后进行 dp 时要用两个二分的 l 而不是 r? r 难道不才是最后一个符合条件的 mid 吗
以及为什么手动调整二分次数时,设为55>50的时候答案出错?按理说二分次数越多答案不应该越精确吗)还是说精度炸掉了)
最后输出答案的时候为什么必须乘以a,b而不是 dp 后的numa,numb啊)
蒟蒻问题有点多)求教