题意:
某公司要建立一套通信系统,该通信系统需要n种设备,而每种设备分别可以有m1、m2、m3、...、mn个厂家提供生产,而每个厂家生产的同种设备都会存在两个方面的差别:带宽bandwidths 和 价格prices。
现在每种设备都各需要1个,考虑到性价比问题,要求所挑选出来的n件设备,要使得B/P最大。
我们定义状态dp 【i】【j】 表示选择了前 i 个宽带其容量为 j 的最小费用。
很容易得到转移方程 :dp【i】【j】=min(dp【i】【j】,dp【i-1】【k】+p);
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <map>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAX = 1e5+10;
int Dp[120][1200];//买i件设备时,最小值为k时的花费
int main()
{
int n,T,m,b,p;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(Dp,INF,sizeof(Dp));
for(int i=0;i<=1200;i++)//当没有一件设备是,自然p为零
{
Dp[0][i]=0;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&m);
for(int j=1;j<=m;j++)
{
scanf("%d %d",&b,&p);
for(int k=0;k<1200;k++)
{
if(b<=k)//当买的b值比k值小时,说明在你买的设备中最小的为b,所以在买i-1件设备中花费+p与Dp[i][b]取小值
{
Dp[i][b]=min(Dp[i-1][k]+p,Dp[i][b]);
}
else
{
Dp[i][k]=min(Dp[i][k],Dp[i-1][k]+p);//买的b值比k值大时,k是买的设备中的最小值,同理
}
}
}
}
double ans=0;
for(int i=1;i<1200;i++)
{
if(Dp[n][i]!=INF)
{
if(ans<(i*1.0/Dp[n][i]))//遍历找出b/p的最大值
{
ans=(i*1.0/Dp[n][i]);
}
}
}
printf("%.3f\n",ans);
}
return 0;
}