POJ 1018 - Communication System

题目是说,要采购n个设备,每个设备i有m[i]个生产商,第j个生产商的带宽是b[i][j],价格是p[i][j],求一种采购方案,使得B/P最大。这里B是指所有设备中带宽b的最小值,P是指总价格。只需要输出B/P。

很容易想到枚举,将每个设备的每个生产商作为B,再依次用贪心选择满足b>=B且p最小的其他设备。不断更新这个B/P值,最后可得到最优值。

不过这样子算下来时间复杂度偏大,所以还得优化。

注意到某些生产商的b值不可能作为B,这个条件可以作为剪枝。事先计算好maxB,表示B值上限。

对于每个设备i,求出b[i][j]的最大值,最后取这些最大值中的最小值,即是maxB。如果B>maxB,那么就会有设备所有生产商都不满足条件b>=B,矛盾。

网上看到的解法还有很多优化处理,比如排序等等,但我只用这一个剪枝已经可以AC。

还有一点,题目最后要求Round 3位小数,我直接截断(没有四舍五入)居然也过了。

附上代码:

#include <iostream>
#include <iomanip>

#define INF 0x7fffffff

using namespace std;

int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		int n, m[101], b[101][101], p[101][101], maxB = INF;
		cin >> n;
		for (int i = 1; i <= n; i++)
		{
			int max = 0;
			cin >> m[i];
			for (int j = 1; j <= m[i]; j++)
			{
				cin >> b[i][j] >> p[i][j];
				if (b[i][j] > max)
					max = b[i][j];
			}
			if (max < maxB)
				maxB = max;
		}

		/* enumerate each manufacturer, assuming it has the minimal bandwidth of all,
		   then find the minimal sum of prices. */
		double ans = 0;
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= m[i]; j++)
			{
				int B = b[i][j], P = p[i][j];
				bool ok = true;

				if (B > maxB) continue;

				/* start searching */
				for (int ii = 1; ii <= n; ii++)
				{
					if (ii != i)
					{
						int min_p = INF;
						for (int jj = 1; jj <= m[ii]; jj++)
						{
							if (b[ii][jj] >= B && p[ii][jj] < min_p)
								min_p = p[ii][jj];
						}
						P += min_p;
					}
				}

				if ((double)B / P > ans)
					ans = (double)B / P;
			}
		}

		cout << setiosflags(ios::fixed) << setprecision(3) << ans << endl;
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值