POJ2976 Dropping tests 二分搜索

来源:互联网 发布:nginx lua waf 安装 编辑:程序博客网 时间:2024/05/21 02:32

         题目大意是,两对数列ai,bi 其中ai <= bi,现在可以从中取走K对,使得剩下的所有ai / bi 的和最大。

         这题一开始拿到会以为直接对ai / bi的值进行排序后选取最大的那几个,但是实际上不是,可以自己举出反例。设C(x):=剩下所有ai / bi的和不小于x。此时,需要对ai - bi * x进行排序,从大到小依次选择求和,大于0的话就说明C(x)成立。

#include <stdio.h>#include <vector>#include <math.h>#include <string.h>#include <string>#include <iostream>#include <queue>#include <list>#include <algorithm>#include <stack>#include <map>using namespace std;struct SCORE{int ivalue;int bvalue;};SCORE values[1001];double X = 0;int compp(const void* a1, const void* a2){SCORE* score1 = (SCORE*)a1;SCORE* score2 = (SCORE*)a2;double dis = score2->ivalue - score2->bvalue * X - (score1->ivalue - score1->bvalue * X);if (dis > 0){return 1;}else if (dis < 0){return -1;}elsereturn 0;}bool CC(double x, int n, int k){int select = n - k;X = x;qsort(values, n, sizeof(SCORE), compp);long double sum = 0;for (int i = 0; i < select; i++){sum += (values[i].ivalue  - values[i].bvalue * x);}if (sum - 0.0 >= 0){return true;}elsereturn false;}int main(){#ifdef _DEBUGfreopen("d:\\in.txt", "r", stdin);#endifint n, k;while (scanf("%d %d", &n, &k) != EOF){if (n == 0 && k ==0){break;}for (int i = 0; i < n; i++){scanf("%d", &values[i].ivalue);}for (int i = 0; i < n; i++){scanf("%d", &values[i].bvalue);}double l = 0;double r = 1.0;for (int i = 0; i < 100; i++){double mid = (l + r) / 2;if (CC(mid, n, k)){l = mid;}elser = mid;}printf("%d\n", (int)(l * 100 + 0.5));}return 1;}


0 0
原创粉丝点击