Mn Zn 求助
查看原帖
Mn Zn 求助
125355
Mihari楼主2021/3/17 21:33

rt,交到 CF\tt CF 上,一直说我 test#5\tt 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

精度已经控制在 10410^{-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;
}
2021/3/17 21:33
加载中...