poj 1018 求B/P最大值

动态规划方法参照:http://hi.baidu.com/guzhou_diaoke/item/b7d0840e1461919ba3df431f

题目大意:有n件商品,每件商品有m个制造商,每个制造商制造的商品有不同的 带宽和价格,每件商品必须选一个制造商,最后的带宽是所有带宽中的最小值,价值是所有商品的总价格,目的是使B/P最大,输出最大的B/P的值。

解题思路:动态规划

dp[i][j]表示选了前i件商品,最小带宽为j时的价值总和。

那么求B/P最大,则要使P尽量的小

那么tb = min(j, b[k])

dp[i][tb] = min(dp[i][tb], dp[i-1][j] + p[k]);

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

const int maxn = 101;
const int maxm = 1010;

int dp[maxn][maxm];
int t, n;
int m, b[maxn], p[maxn];

int main()
{
	
	scanf("%d", &t);
	while(t-- != 0)
	{
		memset(dp, -1, sizeof(dp));
		scanf("%d", &m);
		int maxb = 0;
		for(int i = 1; i <= m; i++)
		{
			scanf("%d", &n);
			for(int k = 1; k <= n; k++)
			{
				scanf("%d %d", &b[k], &p[k]);
				maxb = max(maxb, b[k]);
			}
			
			if(1 == i)
			{
				for(int k = 1; k <= n; k++)
					dp[1][b[k]] = p[k];
				continue;
			}
			
			for(int j = 0; j <= maxb; j++)
			{
				if(dp[i-1][j] != -1)
				{
					for(int k = 1; k <= n; k++)
					{
						int tb = min(j, b[k]);
						if(dp[i][tb] == -1)
							dp[i][tb] = dp[i - 1][j] + p[k];
						else
							dp[i][tb] = min(dp[i][tb], dp[i - 1][j] + p[k]);
					}
				}
			}
		}
		double ans = 0;
		for(int k = 0; k <= maxb; k++)
		{
			if(dp[m][k] != -1)
				ans = max(ans, 1.0 * k / dp[m][k]);
		}
		printf("%.3f\n", ans);
	}
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值