POJ 2976 Dropping tests

【题目大意】

在一场考试中,你有n个测试,你在b道问题内答对了a道,最后你的成绩为:

他会先给你各个测试的ai和bi,然后给出一个正整数k,表示你可以放弃k个测试,例如给你3个测试分别为(5,5),(0,1),(2,6),那么最后成绩为100*((5+0+2)/(5+1+6))=50,如果不选第三个,那么成绩为100*((5+0)/(5+1))≈83.3,最后四舍五入得到83。

【输入格式】

输入包括多组数据,每组数据有三行,第一行为两个整数n,k,1≤n≤1000,0≤k<n。

第二行是n个数据,表示a[i];第三行是n个数据,表示b[i],0≤a[i],b[i]≤1,000,000,000。数据以“0,0”结束。

【输出格式】

对于每一组数据,输出一个整数表示在除掉k门后最高的成绩。

【样例输入】

3 1

           5 0 2

           5 1 6

           4 2

           1 2 7 9

           5 6 7 9

           0 0

【样例输出】

           83

           100

【题目分析】

           作为蒟蒻,能打打的就这种一眼能看出来的板子题了。。。

          分数规划,直接二分能达到的最大成绩,score[i]=a[i]-mid*b[i],最后取后k位加起来,如果大于等于0说明可能取小了,否则取大了,不断调整,最后就是答案(要四舍五入)

【代码(写得丑不要吐槽)】

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const double eps=1e-6;
const int MAXN=1e3+10;
const int INF=0x3f3f3f3f;

int n,m;
int a[MAXN],b[MAXN];
double score[MAXN];

int main()
{
	while(scanf("%d%d",&n,&m)&&n!=0)
	{
		for(int i=1;i<=n;++i)
		  scanf("%d",&a[i]);
		for(int i=1;i<=n;++i)
		  scanf("%d",&b[i]);
		double l=0,r=INF*1.0;
		while(l+eps<r)
		{
			double mid=(l+r)/2.0;
			for(int i=1;i<=n;++i)
			  score[i]=a[i]-b[i]*mid;
			sort(score+1,score+n+1);
			double tot=0.0;
			for(int i=m+1;i<=n;++i)
			  tot+=score[i];
			if(tot>=0.0)
			  l=mid;
			else
			  r=mid;
		}
		cout<<(int)(l*100+0.5)<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/g21glf/article/details/82708116