这道稀里糊涂就过了。算是很顺利。想法也很朴素。
对每个设备按照制造商的带宽从大到小排序。这时可以除去那些带宽低但是价格高的制造商。比如(80, 25)和(120, 80)。
然后采用类似归并排序的方法。
1. 初始化所有设备的制造商指针都指向第一个制造商,
2. 确定最小的带宽,更新其他设备的制造商指针(其他设备可能有比这个最小带宽大的制造商)。着这个过程中可以确定在当前最小带宽下,每个设备的最小价格。
3. 将价格加起来,算一次B/P。更新最大的B/P。
4. 每个设备都指向下一个制造商。重复2知道每个设备都指向了最后一个制造商。
thestoryofsnow | 1018 | Accepted | 256K | 16MS | C++ | 3258B |
/*
ID: thestor1
LANG: C++
TASK: poj1018
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>
using namespace std;
const int MAXN = 100;
const int MAXMI = 100;
class Device
{
public:
int bandwidth, price;
Device()
{
Device(-1, -1);
}
Device(int bandwidth, int price)
{
this->bandwidth = bandwidth;
this->price = price;
}
// inline bool operator< (const Device &rhs) const
// {
// return bandwidth < rhs.bandwidth || (bandwidth == rhs.bandwidth && price >= rhs.price);
// }
inline bool operator> (const Device &rhs) const
{
return bandwidth > rhs.bandwidth || (bandwidth == rhs.bandwidth && price <= rhs.price);
}
};
int main()
{
int mi[MAXN], pi[MAXN];
Device devices[MAXN][MAXMI];
int T;
scanf("%d", &T);
for (int t = 0; t < T; ++t)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%d", &mi[i]);
for (int j = 0; j < mi[i]; ++j)
{
scanf("%d%d", &devices[i][j].bandwidth, &devices[i][j].price);
}
}
for (int i = 0; i < n; ++i)
{
sort(devices[i], devices[i] + mi[i], greater<Device>());
}
// printf("[debug]devices:\n");
// for (int i = 0; i < n; ++i)
// {
// printf("[%d]: ", i);
// for (int j = 0; j < mi[i]; ++j)
// {
// printf("(%d, %d) ", devices[i][j].bandwidth, devices[i][j].price);
// }
// printf("\n");
// }
for (int i = 0; i < n; ++i)
{
int p = 0, q = 1;
while (q < mi[i])
{
while (q < mi[i] && (devices[i][q].bandwidth <= devices[i][p].bandwidth && devices[i][q].price >= devices[i][p].price))
{
q++;
}
if (q < mi[i])
{
p++;
devices[i][p] = devices[i][q];
q++;
}
}
mi[i] = p + 1;
}
// printf("[debug]devices:\n");
// for (int i = 0; i < n; ++i)
// {
// printf("[%d]: ", i);
// for (int j = 0; j < mi[i]; ++j)
// {
// printf("(%d, %d) ", devices[i][j].bandwidth, devices[i][j].price);
// }
// printf("\n");
// }
double maxbp = 0.0;
memset(pi, 0, n * sizeof(int));
bool moveforward = true;
while (moveforward)
{
int minpi = 0;
for (int i = 1; i < n; ++i)
{
if (devices[i][pi[i]].bandwidth < devices[minpi][pi[minpi]].bandwidth)
{
minpi = i;
}
}
int sumprice = 0;
for (int i = 0; i < n; ++i)
{
int price = devices[i][pi[i]].price;
if (i != minpi)
{
pi[i]++;
while (pi[i] < mi[i] && devices[i][pi[i]].bandwidth >= devices[minpi][pi[minpi]].bandwidth)
{
price = min(price, devices[i][pi[i]].price);
pi[i]++;
}
pi[i]--;
}
sumprice += price;
}
double bp = devices[minpi][pi[minpi]].bandwidth * 1.0 / sumprice;
maxbp = max(maxbp, bp);
moveforward = false;
for (int i = 0; i < n; ++i)
{
if (pi[i] != mi[i] - 1)
{
pi[i]++;
moveforward = true;
}
}
}
printf("%.3f\n", maxbp);
}
return 0;
}