01分数规划问题
题目:
有一堆物品,每一个物品有一个收益ai,一个代价bi,选择n-k个物品使选择的最大。
输入输出格式:
第一行输入n,k。第二行是每个物品的收益,第三行是每个物品的代价。
输入样例:
3 1
5 0 2
5 1 6
输出样例:
0.83
解题思路:
我们设(选择的n-k个物品),则
这时就可以使用二分,尽可能使v大的情况下不断缩小两边的范围直到满足精度。
比如从0~1e10之间查找尽可能大的v的值。
如果,表示v取小了,否则表示v取大了
#include<cstdio>
#include<algorithm>
using namespace std;
const double eps=1e-7;
double a[100],b[100],temp[100];
int n,k;
double cal(double v)
{
for(int i=0;i<n;i++)//计算a(x)-v*b(x)
{
temp[i]=a[i]-v*b[i];
}
sort(temp,temp+n);//排序
double sum=0;
for(int i=k;i<n;i++)//选择最大的n-k个
{
sum+=temp[i];
}
return sum;
}
double solve()
{
double l=0,r=1e10,mid;
while(r-l>eps)
{
mid=(l+r)/2;
if(cal(mid)>=0) l=mid;
else r=mid;
}
return l;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%lf",&a[i]);
}
for(int i=0;i<n;i++)
{
scanf("%lf",&b[i]);
}
printf("%.2f",solve());
return 0;
}