虽然网上把这个题分到DP中,不过这分明就是枚举。
COPY 一段别人的分析:
(1)题目意思大概就是有n个devices,每个都需要一个bandwidth,而这个会有很多商家提供,价格不同,现在在n个中,每个选一个,但是着n个中选B最小的,而所有选的price和最小,即是B/p最大。-
(2)题目讲在不同设备中个取出一种设备,使得这些设备带宽的最小值和它们价值的总和的比最大.
贪心思路:
1,获得一个最小和最大带宽:最小带宽是各个设备最小带宽的最小值,最大带宽是各个设备最大带宽的最小值.
2,从最小值递增到最大值进行寻找,计算各种设备价钱的最小值的和,然后计算出一个比值,如果比值比当前比值大,更换当前比值;
3,重复2直到结束.
为了快一点,我先进行排序。
我的CODE:
/*
* POJ-1018 communication system
* mike-w
* 2011-10-23
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 111
typedef struct _device
{
int width;
int price;
}device;
int T,N;
device dev[SIZE][SIZE];
int b[SIZE*SIZE],cnt[SIZE];;
int comp1(const void* e1,const void *e2)
{
return *((int*)e1) - *((int*)e2);
}
int comp2(const void *e1, const void *e2)
{
return ((device*)e1)->price - ((device*)e2)->price;
}
int main(void)
{
int i,j,k;
int sum,min;
float max,ratio;
#ifndef ONLINE_JUDGE
freopen("t.in","r",stdin);
#endif
scanf("%d",&T);
while(T-->0)
{
scanf("%d",&N);
for(i=0;i<N;i++)
{
scanf("%d",cnt+i);
for(j=0;j<cnt[i];j++)
{
scanf("%d%d",&(dev[i][j].width),&(dev[i][j].price));
b[++b[0]]=dev[i][j].width;
}
qsort(dev[i],cnt[i],sizeof(device),comp2); /* ascending order by price */
}
qsort(b+1,b[0],sizeof(int),comp1); /* ascending order as well */
b[b[0]+1]=-1;
max=0.0;
for(i=1;i<=b[0];i++) /* b[i] <- minimum of bandwidth */
{
sum=0;
if(b[i]!=b[i+1]) /* avoid repeatation */
{
for(j=0;j<N;j++)
{
min=0;
for(k=0;k<cnt[j];k++)
if(dev[j][k].width>=b[i])
{
min=dev[j][k].price;
break;
}
if(k==cnt[j]) /* break */
i=b[0]+1,j=N;
else
sum+=min;
}
ratio=(float)b[i]/(float)sum;
if(ratio>max)
max=ratio;
}
}
printf("%.3f\n",max);
}
return 0;
}