rt,交到 CF 上,一直说我 test#5 因为精度问题挂掉了,然鹅第五组是这样的:
7 4 4
0.642 0.036 0.552 0.936 0.866 0.905 0.409
0.100 0.247 0.172 0.859 0.036 0.672 0.255
而答案是这样的:
4.4030560000000003029
我使用我的代码在本地测评,会输出:
4.40306
精度已经控制在 10−4 次方之内了啊,为什么会挂掉啊,是评测姬环境不同吗?
代码在这里:
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
template<class T>inline T readin(T x){
x=0; int f=0; char c;
while((c=getchar())<'0' || '9'<c) if(c=='-') f=1;
for(x=(c^48); '0'<=(c=getchar()) && c<='9'; x=(x<<1)+(x<<3)+(c^48));
return f? -x: x;
}
const int maxn=2e3;
const double eps=1e-8;
int n, a, b;
double p[maxn+5], u[maxn+5];
inline void input(){
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]);
}
inline int compare(double x, double y){
return (x-y>-eps)-(x-y<eps);
}
struct node{
double exp;
int cnt1, cnt2;
node(){}
node(double E, int C1, int C2): exp(E), cnt1(C1), cnt2(C2){}
inline node operator +(const node rhs) const{
return node(exp+rhs.exp, cnt1+rhs.cnt1, cnt2+rhs.cnt2);
}
inline int operator <(const node rhs) const{
if(compare(exp, rhs.exp)==0)
return cnt1==rhs.cnt1? cnt2<rhs.cnt2: cnt1<rhs.cnt1;
return compare(exp, rhs.exp)<0;
}
}f[maxn+5][4];
// 0: use nothing
// 1: use ball p
// 2: use ball u
// 3: just fuck it!
inline void getf(double x, double y){
// printf("<-------------- Now getf: x == %f, y == %f -------------->\n", x, y);
f[1][0]=node(0, 0, 0);
f[1][1]=node(p[1]-x, 1, 0);
f[1][2]=node(u[1]-y, 0, 1);
f[1][3]=node(p[1]-x+(1-p[1])*u[1]-y, 1, 1);
// printf("f[%d, %d] == (%f, %d, %d)\n", 1, 0, f[1][0].exp, f[1][0].cnt1, f[1][0].cnt2);
// printf("f[%d, %d] == (%f, %d, %d)\n", 1, 1, f[1][1].exp, f[1][1].cnt1, f[1][1].cnt2);
// printf("f[%d, %d] == (%f, %d, %d)\n", 1, 2, f[1][2].exp, f[1][2].cnt1, f[1][2].cnt2);
// printf("f[%d, %d] == (%f, %d, %d)\n", 1, 3, f[1][3].exp, f[1][3].cnt1, f[1][3].cnt2);
for(int i=2; i<=n; ++i){
f[i][0]=max(max(f[i-1][0], f[i-1][1]), max(f[i-1][2], f[i-1][3]));
f[i][1]=f[i][0]+node(p[i]-x, 1, 0);
f[i][2]=f[i][0]+node(u[i]-y, 0, 1);
f[i][3]=f[i][0]+node(p[i]-x+(1-p[i])*u[i]-y, 1, 1);
// printf("f[%d, %d] == (%f, %d, %d)\n", i, 0, f[i][0].exp, f[i][0].cnt1, f[i][0].cnt2);
// printf("f[%d, %d] == (%f, %d, %d)\n", i, 1, f[i][1].exp, f[i][1].cnt1, f[i][1].cnt2);
// printf("f[%d, %d] == (%f, %d, %d)\n", i, 2, f[i][2].exp, f[i][2].cnt1, f[i][2].cnt2);
// printf("f[%d, %d] == (%f, %d, %d)\n", i, 3, f[i][3].exp, f[i][3].cnt1, f[i][3].cnt2);
}
}
inline double check(double x){
double l=0, r=1, mid;
for(int tmp=1; tmp<=100; ++tmp){
mid=(l+r)/2;
getf(x, mid);
f[n][0]=max(max(f[n][0], f[n][1]), max(f[n][2], f[n][3]));
if(f[n][0].cnt2<=b) r=mid;
else l=mid;
}
return mid;
}
signed main(){
input();
double l=0, r=1, mid, y;
for(int tmp=1; tmp<=100; ++tmp){
mid=(l+r)/2;
y=check(mid);
if(f[n][0].cnt1<=a) r=mid;
else l=mid;
}
printf("%.5f\n", f[n][0].exp+a*mid+b*y);
return 0;
}