您的位置:首页 > 其它

ZOJ 1409 Communication System

2015-02-03 22:43 134 查看
这题用的是贪心算法,不过在贪心之前还是要进行部分处理的。

首先就是题目要求B/P尽可能的大,所以P应该尽可能的小,B应该尽可能的大。但是B和P的处理方式是不一样的,B是所有带宽中最小的那一个,P是所有设备的总价钱,所以我能想到一个方法就是一个一个的枚举B,本来我是不敢这样想的,可是题目给的时间比较长,我觉得应该问题不大,当我运行之后,竟然只是0ms,让我吃了一惊。然后再选择设备,这时候就要用到贪心:

给定一个band,对于一个设备,在各个生产厂家之间的选择,显然带宽要比band大,在这个中选择价钱最便宜的。

我的具体处理细节如下:

1、对所有的band进行升序排序,枚举的时候从最小的开始,当枚举到一个band,某一个设备无法选出,也就是说该设备的各个生产厂家的带宽都没有band大,那么就结束了。

2、对每个设备的band进行降序排序,这样在查找最小的price的时候比较方便。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
const int inf=1<<28;
int band[10002],num[102];
struct Device
{
int band;
int price;
}device[102][102];
int n,m;
int solve(int t)
{
int t1=0,t2;
for(int i=1;i<=n;i++)
{
t2=inf;
for(int j=1;j<=num[i];j++)
{
if(device[i][j].band<t)
break;
if(t2>device[i][j].price)
t2=device[i][j].price;
}
if(t2==inf)
return -1;
t1+=t2;
}
return t1;
}
bool cmp(Device a,Device b)
{
return a.band>b.band;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int top=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&m);
num[i]=m;
for(int j=1;j<=m;j++)
{
scanf("%d%d",&device[i][j].band,&device[i][j].price);
band[top++]=device[i][j].band;
}
}
sort(band+1,band+top);
for(int i=1;i<=n;i++)
sort(device[i]+1,device[i]+num[i]+1,cmp);
int t_band=0,sum;
double ans=0.0;
for(int i=1;i<top;i++)
{
if(band[i]==t_band)//如果相同的带宽已经处理过,那么就不用处理了
continue;
t_band=band[i];
sum=solve(band[i]);
if(sum==-1)
break;
double b_p=band[i]*1.0/sum;
if(ans<b_p)
ans=b_p;
}
printf("%.3lf\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: