01分数规划是这样的一类问题,有一堆物品,每一个物品有一个收益ai,一个代价bi,我们要求一个方案使选择的∑ai/∑bi∑ai/∑bi最大。
两种做法:1、二分不断迫近答案 2、在前一个解的基础上精确下一个解
模板如下(例题为2018牛客网多校第5场A题)
1、二分求解
struct node{
double s,c,ans;
}cur[MAXN];
bool cmp(double a,double b)
{
return a>b;
}
bool check(double x)
{
for(int i=1;i<=n;i++)
ans[i]=cur[i].s*(cur[i].c-x);
sort(ans+1,ans+n+1,cmp);
double sum=0;
for(int i=1;i<=n-k;i++)
sum+=ans[i];
return sum>0;
}
void solve()
{
double l=0,r=100,m;
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lf",&cur[i].s);
for(int i=1;i<=n;i++)
scanf("%lf",&cur[i].c);
while(r-l>1e-6){
m=(l+r)/2;
if(check(m))
l=m;
else
r=m;
}
}
r的范围需要根据题意去自己判定
2、根据前一个解求解
struct node{
double s,c,ans;
}cur[MAXN];
bool cmp(node a,node b)
{
return a.ans>b.ans;
}
double check(double x)
{
for(int i=1;i<=n;i++)
cur[i].ans=cur[i].s*(cur[i].c-x);
sort(cur+1,cur+n+1,cmp);
double aa=0,bb=0;
for(int i=1;i<=n-k;i++)
{
aa+=cur[i].c*cur[i].s;
bb+=cur[i].s;
}
return aa/bb;
}
void solve()
{
double da=1,gj=0;
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lf",&cur[i].s);
for(int i=1;i<=n;i++)
scanf("%lf",&cur[i].c);
while(da-gj>1e-6){
gj = da;
da=check(da);
}
}
链接:https://www.nowcoder.com/acm/contest/143/A
来源:牛客网
题目描述
Kanade selected n courses in the university. The academic credit of the i-th course is s[i] and the score of the i-th course is c[i].
At the university where she attended, the final score of her is
Now she can delete at most k courses and she want to know what the highest final score that can get.
输入描述:
The first line has two positive integers n,k
The second line has n positive integers s[i]
The third line has n positive integers c[i]
输出描述:
Output the highest final score, your answer is correct if and only if the absolute error with the standard answer is no more than 10-5
示例1
输入
复制
3 1
1 2 3
3 2 1
输出
复制
2.33333333333
说明
Delete the third course and the final score is
备注:
1≤ n≤ 105
0≤ k < n
1≤ s[i],c[i] ≤ 103