0/1分数规划:给定n个a,n个b。求一组解xi(1<=i<=n,xi==0或1)使下式最大化:
我们不妨假设存在一个解使得上式等于L。
那么:考虑这个式子
如果这个式子大于0,那么就有:
L比实际值要小(可能L就是解)
如果这个式子小于0,有:
L比实际值要大(此时L不可能是解)
综上 二分即可。
这一题不过是加了个只选n-k个的条件而已
#include <cstdio>
#include<algorithm>
using namespace std;
typedef long double ld;
typedef long long ll;
const int M = 1e5+7;
const double eps=1e-8;
double a[M],b[M],c[M];
int n,k;
bool ck(double L)
{
//选n-k个数
for(int i=1;i<=n;i++)c[i]=a[i]-L*b[i];
sort(c+1,c+1+n);
double ans=0;
for(int i=1;i<=n-k;i++)ans+=c[n-i+1];
if(ans+eps>=0)return true;
return false;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
if(n==0)break;
for(int i=1;i<=n;i++)scanf("%lf",&a[i]);
for(int i=1;i<=n;i++)scanf("%lf",&b[i]);
//sum ai*xi -L*bi*xi 这个值大于0,L偏小,否则L偏大
double l=-1e13,r=1e13;
double ans=0;
while(l+eps<=r)
{
double mid=(l+r)/2;
if(ck(mid))ans=mid,l=mid;
else r=mid;
}
printf("%.0f\n",ans*100);
}
return 0;
}