某公司要建立一套通信系统,该通信系统需要n种设备,而每种设备分别可以有m1、m2、m3、…、mn个厂家提供生产,而每个厂家生产的同种设备都会存在两个方面的差别:带宽bandwidths 和 价格prices。
现在每种设备都各需要1个,考虑到性价比问题,要求所挑选出来的n件设备,要使得B/P最大。
其中B为这n件设备的带宽的最小值,P为这n件设备的总价。
方法1:枚举法
枚举存在的带宽值,作为当前最低的带宽值,它的上限是min(每种零件带宽的最大值)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
using namespace std;
int t, n;
const int maxn = 105;
struct node {
int type;
int p;
int b;
};
bool cmp(node a, node b) {
if (a.b < b.b)
return true;
else if (a.b == b.b)
return a.p < b.p;
return false;
}
node a[105][105];
int maxB[maxn];
int barr[maxn][maxn]; //用于二分查找
//int sortb[maxn];
int maxminb; //各类零件最大带宽中的最小值
set<int>sb;
int cnt[maxn];
int main()
{
scanf("%d", &t);
for (int i = 0; i < t; i++) {
double ans = -1;
memset(maxB, -1, sizeof maxB);
maxminb = 2000000000;
memset(cnt, 0, sizeof cnt);
scanf("%d", &n);
for (int j = 0; j < n; j++) { //j为type
int m;
scanf("%d", &m);
//int bmax= -1;
for (int k = 0; k < m; k++) {
cnt[j]++;
int b, p;
scanf("%d%d", &b, &p);
a[j][k].b = b;
a[j][k].p = p;
a[j][k].type = j;
sb.insert(b);
maxB[j] = max(maxB[j], b);
}
sort(a[j], a[j] + m, cmp);
for (int k = 0; k < m; k++){
barr[j][k] = a[j][k].b;
}
//maxB[j] = bmax;
}
for (int j = 0; j < n; j++) {
maxminb = min(maxminb, maxB[j]);
}
for (set<int>::iterator it = sb.begin(); it != sb.end(); it++) { //以it为最小带宽
if (*it > maxminb)
break;
int sumprice = 0;
//int flag = 0;
for (int j = 0; j < n; j++) {
int p = lower_bound(barr[j], barr[j] + cnt[j], *it)- barr[j];
int minp = 2000000000;
for (int q = p; q < cnt[j]; q++) {
minp = min(minp, a[j][q].p);
}
sumprice += minp;
}
ans = max(ans, *it*1.0 / sumprice);
}
printf("%.3llf\n", ans);
}
return 0;
}