POJ2976Dropping tests

(又一道G++不过C++能过的神题,想想也是,毕竟G++会丢精)

一道01分数规划的入门题,真的是裸题

01分数规划是一类求解最大比值的问题,通俗一点就是你有一些物品,他们有各自的价值和重量,你需要选出一些物品使他们的总价值/总质量最大

我们现在假定L=Σ(ai*xi)/Σ(bi*xi),那么移项Σ(ai*xi)=Σ(bi*xi)*L,那么显然当比值最大时,L有最大值,怎么得到L?二分呗

我们二分一个L,然后计算一下Σ(ai-L*bi),看他是不是大于零,大于零,说明L还可以取到更大,也就是说L还有更优解,小于零的话,说明当前的值已经到了顶端,需要减小,然后我一直二分,知道到达条件,就可以了

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=1050;
const double eps=1e-7;
double a[M],b[M];
int n,m;
bool check(double x)
{
	double e[M],ans;
	for (int i=1;i<=n;i++)
		e[i]=a[i]-x*b[i];
	sort(e+1,e+n+1);
	for (int i=m+1;i<=n;i++)
		ans+=e[i];
	return ans>0;
}
int main()
{
	while (~scanf("%d%d",&n,&m)&&n)
	{
		for (int i=1;i<=n;i++) scanf("%lf",&a[i]);
		for (int i=1;i<=n;i++) scanf("%lf",&b[i]);
		double l=0.0,r=1.0;
		while (r-l>eps)
		{
			double mid=(l+r)/2.0;
			if (check(mid)) l=mid;
			else r=mid;
		}
		printf("%.0lf\n",l*100.0);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/80906832
今日推荐