PKU ACM 1018 Communication System (DP)

题目链接:Communication System

 

问题描述:

一种通讯系统,由n个零件组成。每个零件有2个属性,带宽和价格。

最终系统的带宽是n个零件中的最小带宽,价格是n个零件价格之和。

求 带宽 / 价格 最大的那个方案的 B / P 值

 

主要思路:

1. 动态规划

2. 用带宽最为索引

     DP[bw] = cost

3. 数据输入的时候,计算出当前输入的最小带宽和最大带宽。可以减少迭代次数。

4. 最后要注意只有一个零件的情况和输出要求小数点后保留3位数字。

     1 1

     1 10 3

 

源代码:

#include <iostream>
#include <iomanip>
using namespace std;

int* bw;
int* cost;
int* DP;
int* tmpDP;
int len, FactoryNum;
int maxbw, minbw;

void GetBP()
{
	int min = 0;
	memset(tmpDP, -1, sizeof(int) * 1000);

	for(int i = minbw; i <= maxbw; i++)
	{
		if(DP[i] != -1)
		{
			for(int j = 0; j < len; j++)
			{
				min = (i < bw[j]) ? i : bw[j];
				if(tmpDP[min] != -1)
				{
					if(bw[j] + DP[i] < tmpDP[min])
						tmpDP[min] = cost[j] + DP[i];
				}
				else
				{
					tmpDP[min] = cost[j] + DP[i];
				}
			}
		}
	}

	int* tmp = DP;
	DP = tmpDP;
	tmpDP = tmp;
	return;
}

void Print()
{
	float bp = 0;
	for(int i = minbw; i <= maxbw; i++)
	{
		if(DP[i] != -1)
		{
			if(((float)i / DP[i]) > bp)
				bp = (float)i / DP[i];
		}
	}
	cout << fixed << setprecision(3) << bp << endl;
}

int main()
{
	int TCNum = 0;
	int PartNum = 0;
	int curbw = 0, curcost = 0;
	FactoryNum = 0;
	DP = new int[1000];
	tmpDP = new int[1000];

	cin >> TCNum;
	
	while(TCNum--)
	{
		cin >> PartNum;
		memset(DP, -1, sizeof(int) * 1000);
		maxbw = 0;
		minbw = 1000;
		int k = 0;

		for(int i = 0; i < PartNum; i++)
		{
			cin >> FactoryNum;
			bw = new int[FactoryNum + 1];
			cost = new int[FactoryNum + 1];
			
			len = FactoryNum;
			for(int j = 0; j < FactoryNum; j++)
			{
				cin >> curbw >> curcost;
				minbw = (curbw < minbw) ? curbw : minbw;
				maxbw = (curbw > maxbw) ? curbw : maxbw;

				for(k = 0; k < j; k++)
				{
					if(curbw < bw[k])
					{
						for(int m = j - 1; m >= k; m--)
						{
							bw[m + 1] = bw[m];
							cost[m + 1] = cost[m];
						}
						bw[k] = curbw;
						cost[k] = curcost;
						break;
					}
					else if(curbw == bw[k])
					{
						if(curcost < cost[k])
						{
							bw[k] = curbw;
							cost[k] = curcost;
							len = len - 1;
							break;
						}
					}
				}

				if(k == j)
				{
					bw[k] = curbw;
					cost[k] = curcost;
				}
			}

			if(i == 0)
			{
				for(int j = 0; j < len; j++)
					DP[bw[j]] = cost[j];
			}
			else
			{	
				GetBP();
			}
		}

		Print();
	}

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值