題意
題目的大概意思是,採購一套通信設備,這套通信設備由若干個設備組成,每個設備可能有若干個不同的廠家,每個廠家生產的設備價格和帶寬均不等,最終這套通信設備的最大帶寬由這若干個設備中帶寬最小的那一個決定,總費用是每個設備的價格之和,求出最大性價比的選擇。即每個設備選擇哪一個廠家生產的可以使得min(bandwidth)/sum(price)最大。
分析
由於最終帶寬由其中某設備決定,那麼直接窮舉所有的可能帶寬即可。假定有編號爲1~n的n個設備,S = {minband(1),minband(2) … minband(n)},爲每個設備不同廠家中選出的最小帶寬集合,T = {maxband(1),maxband(2) …maxband(n)},那麼最終這套設備的帶寬必定在min(S)到min(T)之間。
這樣一來便很簡單了。
代碼如下:
Memory: 340K Time: 63MS Length:48LINES
#include<iostream>
#include<set>
using namespace std;
struct B_P { int bandwidth, price; };
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
int main()
{
int cases = 0;
int devices = 0;
int manufacturers[100] = { 0 };
B_P band_price[100][100];
cin >> cases;
while (cases-- > 0)
{
cin >> devices;
set<int> Set_Band;
int maxband = 0x7FFFFFFF; //int的最大值
for (int i = 0; i < devices; ++i)
{
cin >> manufacturers[i];
int tmpband = 0;
for (int j = 0; j < manufacturers[i]; ++j)
{
cin >> band_price[i][j].bandwidth >> band_price[i][j].price;
Set_Band.insert(band_price[i][j].bandwidth);
tmpband = max(tmpband, band_price[i][j].bandwidth); //找到每個設備的帶寬的最大值
}
maxband = min(maxband, tmpband); //再在這若干個最大值裏取最小的
}
double ratio = 0.0;
for (set<int>::iterator it = Set_Band.begin(); it != Set_Band.end() && *it <= maxband; ++it)
{
int sumprice = 0;
for (int i = 0; i < devices; ++i)
{
int minprice = 0x7FFFFFFF;
for (int j = 0; j < manufacturers[i]; ++j)
if (band_price[i][j].bandwidth >= *it) //找出每個設備的最小价格
minprice = min(minprice, band_price[i][j].price);
sumprice += minprice;
}
ratio = max(ratio, *it / double(sumprice));
}
printf("%.3f\n", ratio);
}
return 0;
}