6700. 【2020.06.07省选模拟】得分(score )

Description

Input

Output

Sample Input

样例 1 输入:
3
4 3 10
1 1 8

样例 2 输入:
4
7 20 15 10
7 20 15 10

Sample Output

样例 1 输出:
0.62500000000

样例 2 输出:
0.31901840491

Data Constraint

Hint

Solution

最优策略是按照ai/ti从大到小做题,因为这样相当于先做在相同时间内能获得最大分值的题目。

然后二分答案,对于每道题目的分值算出来再按照a值的大小顺序看看是否分值符合题目要求,注意价值相同时,时间越小或a越小的排前面。以及注意不同大小的a值才用比较分值大小。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#define I int
#define F(i,a,b) for(I i=a;i<=b;i++)
#define Fd(i,a,b) for(I i=a;i>=b;i--)
#define N 200003
#define ll long long
#define mem(a,b) memset(a,b,sizeof a)
#define ld long double
using namespace std;
I n,t[N];
ld l=0,r=1,mid,ans=1,f[N],T,p=0.00000000001;
struct node{ld a,t,v;I k;}s[N];
I cmp(node x,node y){return x.a>y.a||x.a==y.a&&x.v>y.v;}
I cmp1(node x,node y){return x.v>y.v||x.v==y.v&&x.a<y.a;}
I check(ld x){
	ld now=0;
	F(i,1,n){
		now+=s[i].t;
		f[s[i].k]=s[i].a*(1-(x*now/T));
	}
	F(i,2,n) if(f[i]>f[i-1]&&s[t[i-1]].a>s[t[i]].a) return 0;
	return 1;
}
I main(){
	freopen("score.in","r",stdin);
	freopen("score.out","w",stdout);
	scanf("%d",&n);
	F(i,1,n) scanf("%Lf",&s[i].a);
	F(i,1,n) scanf("%Lf",&s[i].t),s[i].v=s[i].a/s[i].t,T+=s[i].t;
	sort(s+1,s+1+n,cmp);
	F(i,1,n) s[i].k=i;
	sort(s+1,s+1+n,cmp1);
	F(i,1,n) t[s[i].k]=i;
	while(l<=r){
		if(check(mid=(l+r)/2)) l=(ans=mid)+p;
		else r=mid-p;
	}
	printf("%.010Lf",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zsjzliziyang/article/details/107165325