动态规划方法参照: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;
}