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;
}