POJ 2976 Dropping Tests

  http://poj.org/problem?id=2976

  题目大意:给定n个二元组(a,b),扔掉k个二元组,使得剩下的   最大。

  这两天一直在搞分数规划,有了前两道题(3621、2728),这道题就是完完全全的大水题了。

  设 r=100*∑(ai)/∑(bi) ,有

    100*∑(ai)-r*∑(bi)=0

    ∑(100*ai-r*bi)=0

  这个东西是单调的……

  我们可以将每个二元组的得分设为100*a-r*b,然后从大到小排序,取前n-k个得分求和(sum)。若sum>0则说明r还不够大,可以向上二分;反之向下二分……

  我最讨厌精度什么的了……尤其是C++的精度……

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <algorithm>

#define eps 1e-4

using namespace std;



double score[1005];

int a[1005],b[1005],n,k;

bool cmp(double a,double b){return a>b;}



int main(){

	while(scanf("%d%d",&n,&k),n+k){

		for(int i=1;i<=n;i++) scanf("%d",&a[i]);

		for(int i=1;i<=n;i++) scanf("%d",&b[i]);

		double low=0,high=100,mid;

		while(high-low>eps){

			mid=(low+high)/2.0;

			for(int i=1;i<=n;i++) score[i]=a[i]*100.0-b[i]*mid;

			sort(score+1,score+n+1,cmp);

			double sum=0;

			for(int i=1;i<=n-k;i++) sum+=score[i];

			if(sum>0) low=mid;

			else high=mid;

		}

		cout<<(int)(low+.5)<<endl;

	}

	return 0;

}

  

你可能感兴趣的:(test)