# codeforces739e绝对的干货题解！！！！！

1.单独用a类型的球。2.单独用b类型的球。3 a类型和b类型一起用.

//由于这个不是我写的所以我感觉代码有点丑。。。但是能解释清楚
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 2010;
int n, a, b;
double p[N], u[N], q[N];
double f[N][N]; int g[N][N];
#define eps 1e-9
#define nowf (f[i][j])
#define nowg (g[i][j])
int dcmp(double x)
{
if (fabs(x)<eps)return 0;
return ((x>0) ? 1 : -1);
}
void up(double &f1, int &g1, double f2, int g2)
{
if (f2>f1 + eps){ f1 = f2; g1 = g2; }
}
int get(double K)
{
for (int i = 1; i <= n; ++i)
for (int j = 0; j <= a; ++j)
{
nowf = nowg = 0;
up(nowf, nowg, f[i - 1][j], g[i - 1][j]);//这里什么球都没用
up(nowf, nowg, f[i - 1][j] + u[i] - K, g[i - 1][j] + 1);//这里用的是b球因为（b-k)是从b球类分出来的所以用了(b-k)相当于用b
if (j)up(nowf, nowg, f[i - 1][j - 1] + p[i], g[i - 1][j - 1]);//用a球
if (j)up(nowf, nowg, f[i - 1][j - 1] + q[i] - K, g[i - 1][j - 1] + 1);//用a球和b球这里应该写成f+p[i]+(u[i]-k)+p[i]*u[i]就好理解
}
return g[n][a];
}
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", u + i);
for (int i = 1; i <= n; ++i)q[i] = p[i] + u[i] - p[i] * u[i];
double l = -1e4, mid, r = 1e4;
while (r - l>eps)
{
mid = (l + r)*0.5;//二分k值
if (get(mid)<b)r = mid;
else l = mid;
}
printf("%lf\n", f[n][a] + l*b);
return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
double u[3000], v[3000], p[3000];
double expect[3000];
int n, a, b;
int numa[3000], numb[3000];
void test(double aa, double bb)
{
for (int i = 1; i <= n; i++)
{
double d1 = u[i] - aa;
double d2 = v[i] - bb;
double d3 = p[i] - aa - bb;
double d4 = 0;
numa[i] = numa[i - 1];
numb[i] = numb[i - 1];
expect[i] = expect[i - 1];
if (d1 >= d2&&d1 >= d3&&d1 > d4)//比较顺序，和大于等于号是有讲究的。。
{                                 //尽量少用d3，d1和d2在相等时随便选
numa[i] += 1;
expect[i] += d1;
continue;
}
if (d2 >d1&&d2 >= d3&&d2 >d4)
{
numb[i]+= 1;
expect[i]+= d2;
continue;
}
if (d3 > d1&&d3 > d2&&d3 > d4)
{
numb[i] += 1;
numa[i] += 1;
expect[i] +=d3;
}
if (d4 >= d1&&d4 >= d3&&d4 >= d2)continue;
}
}
int main()
{
//double lllll = 0.000000000000000001;
//cout << lllll <<endl;
scanf("%d%d%d", &n, &a, &b);
for (int i = 1; i <= n; i++)
{
scanf("%lf", &u[i]);
}
for (int i = 1; i <= n; i++)
scanf("%lf", &v[i]);
for (int i = 1; i <= n; i++)
p[i] = u[i] + v[i] - u[i] * v[i];
double ll = 0, rr = 1;
double l, r;
while (rr - ll > 1e-12)
{
double mida = (ll + rr) / 2;
l = 0, r = 1;
while (r - l > 1e-12)
{
double midb = (l + r) / 2;
test(mida, midb);
if (numb[n] < b)
r = midb;
else
l = midb;
if (numb[n] == b)break;//同下
}
if (numa[n] < a)
rr = mida;
else
ll = mida;
if (numa[n] == a)break;//如果numa[n]==a的时候此时已经是极限了如果不break 然后ll=mida然后mida上升导致所得解偏小。
}
//	cout << "ll:" << ll << " " << "l:" <<l << endl;
//cout << ll*numa[n] + l*numb[n] << endl;
//	cout << numa[n] << " " << numb[n] << endl;
//cout << expect[n] << endl;
printf("%.5lf", expect[n] + numa[n]*ll + numb[n]*l);//注意这得写法不是 expect[n] + a*ll + b*l
}