POJ 2976 Dropping Tests

分数规划解决二元组问题
本文介绍如何使用分数规划解决给定二元组的最大化问题。通过设定关键参数r,作者提出了一种排序和二分查找的方法来优化解决方案。

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

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

  这两天一直在搞分数规划,有了前两道题(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;
}

  

转载于:https://www.cnblogs.com/Delostik/archive/2011/07/28/2119404.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值