POJ 1018 Communication System 贪心+枚举

看题传送门:http://poj.org/problem?id=1018

题目大意:

某公司要建立一套通信系统,该通信系统需要n种设备,而每种设备分别可以有m个厂家提供生产,而每个厂家生产的同种设备都会存在两个方面的差别:带宽bandwidths 和 价格prices。

现在每种设备都各需要1个,考虑到性价比问题,要求所挑选出来的n件设备,要使得B/P最大。
其中B为这n件设备的带宽的最小值,P为这n件设备的总价。

思路:

贪心+枚举

要使得B/P最大,则B应该尽量大,而P尽量小。

可以按照价格从小到大排序。对于每一件产品,枚举出所有符合其他的bandwiths > 这一件的带宽。

因为把价格进行排序,价格小的在前面,所以可以肯定的是对于每件产品的第一次枚举,就是该次枚举的最优解。

比较每一次的最优解即可。


#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct produce
{
	int b;
	int p;
	bool operator<(const produce &pro)const
	{
		//如果价格一样就把b大的放前面
		if(p==pro.p)
			return b>pro.b;
		return p<pro.p;
	}
};

struct prodece_info
{
	produce data[101];
	int len;
}ps[101];

int n;

double max(double a,double b)
{
	return a<b? b:a;
}

int main()
{
	int t;
	scanf("%d",&t);

	while(t--)
	{
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%d",&ps[i].len);
			for(int j=0;j<ps[i].len;j++)
				scanf("%d%d",&ps[i].data[j].b,&ps[i].data[j].p);
			//按照价格排序
			sort(ps[i].data,ps[i].data+ps[i].len);
		}

		//遍历开始
		double ans=-99999;
		double total_price, bandwidth;

		for(int i=0;i<n;i++)
		{
			for(int j=0;j<ps[i].len;j++)
			{
				//取其中一个b作为最小的
				//之后应该选bandwidth不小于的且price尽量低的
				bandwidth=ps[i].data[j].b;
				total_price=ps[i].data[j].p;
				bool ok=true;
				for(int k=0;k<n;k++)
				{
					if(k==i)
						continue;
					else
					{
						int x=0;
						//注意x合法性判断。都不满足的话。。。。。一开始没注意WA一次
						while(bandwidth > ps[k].data[x].b && x<ps[k].len )
						{
							x++;
						}
						if(x==ps[k].len)
						{
							ok=false;
							break;
						}
						total_price+=ps[k].data[x].p;
					}
				}

				if(ok)
					ans=max(ans,bandwidth/total_price);
			}
		}
		printf("%.3lf\n",ans);
	}
}




你可能感兴趣的:(POJ 1018 Communication System 贪心+枚举)