输入
输入数据第一行为一个整数n,m,接下来2行,每行为n个数,第一行第i个整数vi,第二行第i个整数ci。
输出
一个整数T,表示最大(Σvi)/(Σci),保留三位小数。
0-1分数规划:
设最终答案为R,x[i]为0或1,则 Σ(v[i]*x[i]) / Σ(c[i]*x[i]) = R
即 Σ(v[i]*x[i]) - Σ(c[i]*x[i]*R) =0
即 Σ[(v[i]*x[i]) - (c[i]*x[i]*R)] =0设 f(R)= Σ[(v[i]*x[i]) - (c[i]*x[i]*R)]
二分R,求f(R)=0
当f(R)<0时,R偏大
当f(R)>0时,R偏小
计算每一对 v[i] - (c[i]*R),排序求前m大的和即为f(R) 。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-7;
int n,m,ansv,anst;
struct node
{
int v,t;
}a[210];
int main()
{
scanf("%d %d",&n,&m);
m=n-m;
for(int i=0;i<n;++i)
scanf("%d",&a[i].v);
for(int i=0;i<n;++i)
scanf("%d",&a[i].t);
double L=0.0,R=1000.0;
double t[210];
double mid;
while(L<R+eps)
{
mid=(double)(L+R)/2;
for(int i=1;i<=n;++i)
t[i]=a[i].v-mid*a[i].t;
sort(t,t+n);
double s=0.0;
for(int i=m;i<n;++i)s+=t[i];
if(s>0)L=mid+eps;
else R=mid-eps;
}
printf("%.3lf",mid);
return 0;
}