POJ:http://poj.org/problem?id=1018
解题思路
题意:
要购买一套通讯系统,有一些设备组成,每个设备我们从一些制造商那里购得,带宽(bandwidth)是我们所选择的设备里面最小的带宽,总价格是我们选择的设备的总价格,我们的目标是求出最大的带宽和总价格的比值(B/P)。
思路:
一开始我就想用贪心,每种都选出拥有最大(B/P)的设备,后来发现不行。后来参考了网上的思路,先枚举带宽,再贪心选择价格最小的,最后求出结果。
具体是在输入时就找出所有这些设备中最小的带宽(low)和最大带宽(high)。然后从low递增到high,每个制造商里都选价格最小的设备,这样就能保证B/P最小了。其实还能优化,把每个带宽都记录下来枚举,这样在带宽大小相差较大的情况下可以省下很多时间,好像要用到STL里的set,暂时还不会,以后再说。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define N 101
int main()
{
int i, j;
int t, n, m[N], k;
int band[N][N], price[N][N], low, high, sump, minp;
float ratio;
FILE *file = freopen("in.txt", "r", stdin);
if (!file)
{
printf("error:can not open the txt\n");
return 1;
}
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
low = 0xffff;
high = 0;
for (i = 1; i <= n; i++)
{
scanf("%d", &m[i]);
for (j = 1; j <= m[i]; j++)
{
scanf("%d%d", &band[i][j], &price[i][j]);
if (band[i][j] < low)
low = band[i][j];
if (band[i][j] > high)
high = band[i][j];
}
}
ratio = 0.0;
for (i = low; i <= high; i++) //枚举band
{
sump = 0;
for (j = 1; j <= n; j++)
{
minp = 0xffff;
for (k = 1; k <= m[j]; k++) //贪心选择price
if (band[j][k] >= i && price[j][k] < minp)
{
minp = price[j][k];
}
sump += minp;
}
if (i * 1.0 / sump - ratio > 0)//每次计算sump;
ratio = i * 1.0 / sump;
}
printf("%.3f\n", ratio);
}
return 0;
}
附录:
1 3 3 100 25 150 35 80 25 2 120 80 155 40 2 100 100 120 110
0.649