POJ2976
http://poj.org/problem?id=2976
题意
给出n个对,可以从中最多排除k个对,求∑a/∑b的最大值。
思路
二分法求解,书中例题跟这个题其实是一样的。
这个题对精度的要求其实并不像题目介绍中说的那么低,程序中应该写的更高一些才行。题目说0.001,实际上至少要0.0001.
代码
Source Code
Problem: 2976 User: liangrx06
Memory: 260K Time: 47MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1000;
struct Score {
int a, b;
};
int n, k;
Score s[N];
bool check(double mid)
{
double t[N];
for (int i = 0; i < n; i ++)
t[i] = s[i].a - s[i].b * mid;
sort(t, t+n);
double sum = 0;
for (int i = n-1; i >= k; i --)
sum += t[i];
return sum > 0;
}
int main(void)
{
while ( cin >> n >> k ) {
if (!n && !k) break;
for (int i = 0; i < n; i ++)
scanf("%d", &s[i].a);
for (int i = 0; i < n; i ++)
scanf("%d", &s[i].b);
double lb = 0, ub = 1, mid;
while (ub - lb >= 0.0001) {
mid = (lb + ub) / 2;
if (check(mid)) lb = mid;
else ub = mid;
}
printf("%.0f\n",mid*100);
}
return 0;
}
POJ3111
http://poj.org/problem?id=3111
题意
Demy有n颗钻石,每颗钻石都有价值和质量,现在要带走其中的k颗钻石,要使得单位价值最大,即Σv/Σw的值最大。
思路
与上个题做法基本一样,另外同样要注意精度问题。
代码
Source Code
Problem: 3111 User: liangrx06
Memory: 2592K Time: 3547MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 100000;
const int INF = 0x3fffffff;
struct Score {
int id;
int a, b;
double t;
};
bool cmp(const Score& x, const Score& y)
{
return x.t > y.t;
}
int n, k;
Score s[N];
bool check(double mid)
{
for (int i = 0; i < n; i ++)
s[i].t = s[i].a - s[i].b * mid;
sort(s, s+n, cmp);
double sum = 0;
for (int i = 0; i < k; i ++)
sum += s[i].t;
return sum >= 0;
}
int main(void)
{
cin >> n >> k;
for (int i = 0; i < n; i ++) {
s[i].id = i+1;
scanf("%d%d", &s[i].a, &s[i].b);
}
double lb = 0, ub = INF;
while (ub - lb >= 1e-6) {
double mid = (lb + ub) / 2;
if (check(mid)) lb = mid;
else ub = mid;
}
for (int i = 0; i < k-1; i ++)
printf("%d ", s[i].id);
printf("%d\n", s[k-1].id);
return 0;
}