POJ 1018 解题报告

这道稀里糊涂就过了。算是很顺利。想法也很朴素。

对每个设备按照制造商的带宽从大到小排序。这时可以除去那些带宽低但是价格高的制造商。比如(80, 25)和(120, 80)。

然后采用类似归并排序的方法。

1. 初始化所有设备的制造商指针都指向第一个制造商,

2. 确定最小的带宽,更新其他设备的制造商指针(其他设备可能有比这个最小带宽大的制造商)。着这个过程中可以确定在当前最小带宽下,每个设备的最小价格。

3. 将价格加起来,算一次B/P。更新最大的B/P。

4. 每个设备都指向下一个制造商。重复2知道每个设备都指向了最后一个制造商。

thestoryofsnow1018Accepted256K16MSC++3258B
/* 
ID: thestor1 
LANG: C++ 
TASK: poj1018 
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>

using namespace std;

const int MAXN = 100;
const int MAXMI = 100;

class Device
{
public:
	int bandwidth, price;
	
	Device()
	{
		Device(-1, -1);
	}

	Device(int bandwidth, int price)
	{
		this->bandwidth = bandwidth;
		this->price = price;
	}

	// inline bool operator< (const Device &rhs) const 
	// {
	// 	return bandwidth < rhs.bandwidth || (bandwidth == rhs.bandwidth && price >= rhs.price);
	// }

	inline bool operator> (const Device &rhs) const 
	{
		return bandwidth > rhs.bandwidth || (bandwidth == rhs.bandwidth && price <= rhs.price);
	}
};

int main()
{
	int mi[MAXN], pi[MAXN];
	Device devices[MAXN][MAXMI];

	int T;
	scanf("%d", &T);

	for (int t = 0; t < T; ++t)
	{
		int n;
		scanf("%d", &n);
		for (int i = 0; i < n; ++i)
		{
			scanf("%d", &mi[i]);
			for (int j = 0; j < mi[i]; ++j)
			{
				scanf("%d%d", &devices[i][j].bandwidth, &devices[i][j].price);
			}
		}

		for (int i = 0; i < n; ++i)
		{
			sort(devices[i], devices[i] + mi[i], greater<Device>());
		}

		// printf("[debug]devices:\n");
		// for (int i = 0; i < n; ++i)
		// {
		// 	printf("[%d]: ", i);
		// 	for (int j = 0; j < mi[i]; ++j)
		// 	{
		// 		printf("(%d, %d) ", devices[i][j].bandwidth, devices[i][j].price);
		// 	}
		// 	printf("\n");
		// }

		for (int i = 0; i < n; ++i)
		{
			int p = 0, q = 1;
			while (q < mi[i])
			{
				while (q < mi[i] && (devices[i][q].bandwidth <= devices[i][p].bandwidth && devices[i][q].price >= devices[i][p].price))
				{
					q++;
				}

				if (q < mi[i])
				{
					p++;
					devices[i][p] = devices[i][q];
					q++;
				}
			}
			mi[i] = p + 1;
		}
		
		// printf("[debug]devices:\n");
		// for (int i = 0; i < n; ++i)
		// {
		// 	printf("[%d]: ", i);
		// 	for (int j = 0; j < mi[i]; ++j)
		// 	{
		// 		printf("(%d, %d) ", devices[i][j].bandwidth, devices[i][j].price);
		// 	}
		// 	printf("\n");
		// }

		double maxbp = 0.0;
		memset(pi, 0, n * sizeof(int));
		bool moveforward = true;
		while (moveforward)
		{
			int minpi = 0;
			for (int i = 1; i < n; ++i)
			{
				if (devices[i][pi[i]].bandwidth < devices[minpi][pi[minpi]].bandwidth)
				{
					minpi = i;
				}
			}

			int sumprice = 0;
			for (int i = 0; i < n; ++i)
			{
				int price = devices[i][pi[i]].price;
				if (i != minpi)
				{
					pi[i]++;
					while (pi[i] < mi[i] && devices[i][pi[i]].bandwidth >= devices[minpi][pi[minpi]].bandwidth)
					{
						price = min(price, devices[i][pi[i]].price);
						pi[i]++;
					}
					pi[i]--;
				}
				sumprice += price;
			}

			double bp = devices[minpi][pi[minpi]].bandwidth * 1.0 / sumprice;

			maxbp = max(maxbp, bp);

			moveforward = false;
			for (int i = 0; i < n; ++i)
			{
				if (pi[i] != mi[i] - 1)
				{
					pi[i]++;
					moveforward = true;
				}
			}
		}

		printf("%.3f\n", maxbp);
	}

	return 0;  
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值