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;
}


阅读更多
文章标签: 制造
个人分类: 动态规划 ACM
想对作者说点什么? 我来说一句

openjudge poj 1018假币问题

2012年04月20日 2KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭