北大poj1018题解题报告

//我是莱鸟,多多交流

//380k

//94ms

题目的意思是:每种装备可由多个生产商提供,从每一种装备中选择一个厂家的设备,使得所选的总的各种装备中的最小带宽B与他们的价格之和P的比值B/P达到最大。

解题思路:

准备工作:在输入时,统计所有装备中的最小值min,和每种装备中的最大值max,然后从最大值中选出最小的一个Max。

然后:从最小值min到Max之间枚举所有的可能的结果,并输出最大的一个值

1、对每种装备进行按p的大小进行升序快排。以便之后的查找工作。

2、保存min到Max之间的所有的的B的节点及他们所在行列数,便于之后查询。

3、对min到Max之间的B[i]进行枚举,并进行更新。

4、输出最大的值。

#include <stdlib.h>
#include <stdio.h>
typedef struct Node
{
int bb;
int p;
}Node;
typedef struct BID
{
int bb;//带宽值
int row;//所在的行号
int col;
}BID;
Node node[101][101];//保存节点
BID B[10001];//保存需要枚举的带宽B值
int comp(const void *a,const void *b)
{
BID* x=(BID*)a;
BID* y=(BID*)b;
if(x->bb==y->bb)
{
if(x->row==y->row)
return x->col-y->col;
return x->row-y->row;
}
return x->bb-y->bb;
}
int cmp(const void *a,const void *b)
{
return ((Node*)a)->p-((Node*)b)->p;
}
int main()
{
void search(int num,int index[]);
int max[101];//保存每组的P最大值
int index[101];//保存每行厂家的个数
int n,num;
int i,j,k;
scanf("%d",&n);
while(n-->0)//
{
int min=65535;//保存最小的P值
int count=0;
for(i=0;i<10001;i++)
B[i].bb=0;
scanf("%d",&num);//设备种数
for(i=0;i<num;i++)//输入一组测试数据
{
scanf("%d",&index[i]);
for(j=0;j<index[i];j++)//输入一行数据
{
scanf("%d %d",&node[i][j].bb,&node[i][j].p);
if(node[i][j].bb>max[i])
max[i]=node[i][j].bb;
if(node[i][j].bb<min)
min=node[i][j].bb;
}
}
int Max=65535;//保存最大中的最小P值
for(k=0;k<num;k++)
if(max[k]<Max)
Max=max[k];
for(i=0;i<num;i++) //对各种厂家的设备按P从大到小的顺序升序排序
qsort(node[i],index[i],sizeof(Node),cmp);
for(i=0;i<num;i++)
for(j=0;j<index[i];j++)
if(node[i][j].bb>=min&&node[i][j].bb<=Max)
{
B[count].bb=node[i][j].bb;
B[count].row=i;
B[count++].col=j;
}
qsort(B,count,sizeof(BID),comp); //对B中的值按b为第一关键字,row为第二,cow为第三关键字升序排序
search(num,index);
}
return 1;
}
void search(int num,int index[101])//按B[]中的顺序进行枚举,并不断更新
{
int k=0;
int i,j;
double result=0;
while(B[k].bb)
{
double sum=0;
if(k&&B[k].bb==B[k-1].bb&&B[k].row==B[k-1].row)
{
k++;
continue;
}
int flag=0;
for(i=0;i<num;i++)
{
if(i!=B[k].row)
{
for(j=0;j<index[i];j++)
if(node[i][j].bb>=B[k].bb)//保证每种装备都有一件,否则不更新
{
sum=sum+node[i][j].p;
flag=1;
break;
}
if(flag)
flag=0;
else
break;
}
}
if(i==num)
{
double average;
average=B[k].bb/(sum+node[B[k].row][B[k].col].p);//
if(average>result)
result=average;
}
k++;
}
printf("%.3lf\n",result);
}

原文地址:https://www.cnblogs.com/ltfbk/p/2578535.html