题目链接:http://poj.org/problem?id=1018
方法:枚举+贪心
思路:今天下午没干别的,就玩这个题了,好吧,我承认自己智商捉急。首先,我们要明确题意,题意要求的是最小带宽/价格之和这个值最大,相当于性价比,想想看可能有如下工程背景,这种通讯系统的通讯带宽是受到了最小的那个带宽限制,而价格是要求和的,所以也就不难理解了。明确这一点后,我们就可以想想看怎么搞了。借鉴了网上的一些思路,dp还不会,搜索太麻烦,所以就选择了枚举加贪心的思路。基本思路是,先找出所有的,不管是哪一个厂家的仪器,的所有的带宽,并在其中找出最大带宽和最小带宽。然后,在最大带宽和最小带宽之间遍历,遍历的就是每个仪器的价格和带宽,既然要求B/P最大,那么就让B大,P小。判断条件就是在遍历所有贷款的时候,去查询当前仪器带宽大于目前所遍历的带宽而且其价格还小于当前最小价格,然后把这个带宽作为分母,当前和作为分子,实际上,这就是在求当前枚举带宽下的最优解,然后在此基础上再取全局最优解即可。
有一篇博文写得非常好,在此标记一下链接,以示感谢!
http://m.blog.youkuaiyun.com/blog/Tc_To_Top/43876451
难点:贪心思路,数据的输入处理,要用二维数组。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<climits>
using namespace std;
const int MAX = 200;
int d[MAX][MAX],p[MAX][MAX],num[MAX];
int main()
{
int n,t;
while(cin>>t)
{
while(t--)
{
int maxum = 0;
int minum =INT_MAX ;
cin>>n;
for(int i = 0;i < n;i++)
{
cin>>num[i];
for(int j = 0;j < num[i];j++)
{
cin>>d[i][j]>>p[i][j];
if(d[i][j] < minum)
minum = d[i][j];
if(d[i][j] > maxum)
maxum = d[i][j];
}
}
double ans = 0;
for(int bw = minum;bw <= maxum;bw++)
{
double sum = 0.0;
for(int i = 0;i < n;i++)
{
int minp = INT_MAX;
for(int j = 0;j < num[i];j++)
{
if(d[i][j] >= bw&&p[i][j] < minp)
minp = p[i][j];
}
sum += minp;
}
if(bw/(sum*1.0) > ans)
ans = bw/(sum*1.0);
}
printf("%.3f\n",ans);
}
}
}