大致题意:
某公司要建立一套通信系统,该通信系统需要n种设备,而每种设备分别可以有m1、m2、m3、...、mn个厂家提供生产,而每个厂家生产的同种设备都会存在两个方面的差别:带宽bandwidths 和 价格prices。
现在每种设备都各需要1个,考虑到性价比问题,要求所挑选出来的n件设备,要使得B/P最大。
其中B为这n件设备的带宽的最小值,P为这n件设备的总价。
错误思想:首先,以为只用算出每种设备的B/P ,挑选出每种中最大的计算B/P就可以得到结果,但是实际上,虽然每种的B/P可达到最大,但是不能保证在总体情况下B是每种设备中带宽最小。
思路: 首先固定一个B,假设该B是所选设备中最小的情况(枚举所有的设备的带宽B)。然后再将每种设备的带宽与之比较,若大于等于B且其单价最小,则说明当前B下,B/P是最小的,然后将所有B/P逐个比较,得到最大值,则为结果。
代码(参考别人所得):
#include<iostream>
using namespace std;
int main()
{
int b[110][110],p[110][110],flag[32767],m[110];
int t,n,min,max;
double result;
int low=99999999,heigh = 0;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
low=min=99999999; heigh =max= 0;
memset(flag,0,sizeof(flag));
for(int i=0;i<n;i++)
{
scanf("%d",&m[i]);
for(int j=0;j<m[i];j++)
{
scanf("%d%d",&b[i][j],&p[i][j]);
flag[b[i][j]] = 1; //用flag标记,该带宽存在
if(min>b[i][j]) min=b[i][j];
if(max<b[i][j]) max=b[i][j];
}
}
if(low > min) low = min;
if(heigh < max) heigh = max;
// cout<<"low= "<<low<<" heigh="<<heigh<<endl;
int sum;
result = 0;
for(int i=low ; i<= heigh;i++) //枚举每个可能的最小带宽B
{
if(flag[i]) //只有该带宽值存在时,枚举其他设备才有意义
{//cout<<"************i= "<<i<<endl;
sum = 0;
for(int j=0;j<n;j++)
{int pow=999999999;
for(int k=0;k<m[j];k++)
{
if(b[j][k]>=i && p[j][k] < pow)//保证带宽B固定i时,sum最小(即每种设备的价格最小),才能使B/P最大
{pow = p[j][k]; }
}
sum+=pow;
}
double temp = (double) i*1.0/sum;
if(result < temp) result=temp;
}
}
printf("%.3lf\n",result);
}
return 0;
}