POJ-1018(DP)

本文介绍了一种解决通信系统配置问题的方法,旨在通过贪心算法选择制造商,以达到在设备带宽最小值与总价格之间的最优比值。通过分析设备数量、制造商数量、带宽和价格等数据,实现对通信系统的高效配置。

1018: Communication System

时间限制:

1000ms

内存限制:

65536kB

描述         

We have received an order from Pizoor Communications Inc. for a special communication system. The system consists of several devices. For each device, we are free to choose from several manufacturers. Same devices from two manufacturers differ in their maximum bandwidths(带宽) and prices.
By overall bandwidth (B) we mean the minimum of the bandwidths of the chosen devices in the communication system and the total price (P) is the sum of the prices of all chosen devices. Our goal is to choose a manufacturer for each device to maximize B/P.                               

输入

The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by the input data for each test case. Each test case starts with a line containing a single integer n (1 ≤ n ≤ 100), the number of devices in the communication system, followed by n lines in the following format: the i-th line (1 ≤ i ≤ n) starts with mi (1 ≤ mi ≤ 100), the number of manufacturers for the i-th device, followed by mi pairs of positive integers(132767) in the same line, each indicating the bandwidth and the price of the device respectively, corresponding to a manufacturer.

输出

Your program should produce a single line for each test case containing a single number which isthe maximum possible B/P for the test case. Round the numbers in the output to 3 digits after decimal point.            

样例输入     

1 3     

3 100 25 150 35 80 25         

2 120 80 155 40                

2 100 100 120 110             

样例输出                            

0.649                         

                                                                        

这题不会的,看了下解题报告,了解了一下解题思路.

(1)题目意思大概就是有n个devices,每个都需要一个bandwidth,而这个会有很多商家提供,价格不同,现在在n个中,每个选一个,但是着n个中选B最小的,而所有选的price和最小,即是B/p最大。-
(2)题目讲在不同设备中个取出一种设备,使得这些设备带宽的最小值和它们价值的总和的比最大.
贪心思路:
1,获得一个最小和最大带宽:最小带宽是各个设备最小带宽的最小值,最大带宽是各个设备最大带宽的最小值.
2,从最小值递增到最大值进行寻找,计算各种设备价钱的最小值的和,然后计算出一个比值,如果比值比当前比值大,更换当前比值;
3,重复2直到结束.

 

#include<stdio.h>

#include<string.h>

 

int main()

{

       int i,j,k,m,min,max,high,low,t,sum;

       int b[101][101],p[101][101],num[101],flag[32767];

       double b_p,mmax;

       scanf("%d",&t);    

       while(t--)                 

       {

              memset(flag,0,sizeof(flag));//初始flag为0,用来标记带宽值

              high=32767;

              low=32767; //正整数的可能最大值

              scanf("%d",&m);                      

              for(i=0;i<m;i++)

              {

                     min=10000;//正整数的可能最大值,取决于测试数据是否变态, int型最大是32767, 一般要尽量开大一点

                     max=1;//正整数的可能最小值

                     scanf("%d",&num[i]);//num[i]为各个设备的备用厂商数目

                     for(j=0;j<num[i];j++)

                     {

                            scanf("%d",&b[i][j]);

                            scanf("%d",&p[i][j]);

                            flag[b[i][j]]=1;//当前贷款带宽标记为1

                            if(max<b[i][j])//当前设备最大值

                                   max=b[i][j];                                 

                            if(min>b[i][j])//当前设备最小值

                                   min=b[i][j];     

                     }

                     if(low>min)//各个设备最小带宽中的最小值

                            low=min;

                     if(high>max)//各个设备最大带宽中的最小值

                            high=max;       

              }                                        

              mmax=0;//最终结果

              for(i=low;i<=high;i++)//结合下面的if(flag[i])则无须次次都是利用循环来获得i值,节省了大量时间

              {

                     if(flag[i])//找出经标记过的带宽值(动态规划说白了就是以空间换取时间)

                     {

                            sum=0;                           

                            for(j=0;j<m;j++)   

                            {                                 

                                   min=32767;    

                                   for(k=0;k<num[j];k++)

                                   {

                                          if(i <=b[j][k])

                                          {

                                                 if(min>p[j][k])//获得当前设备所有供应商中最低的价格

                                                        min=p[j][k];

                                          }

                                   }

                                   sum+=min;                                  

                            }

                            b_p=(double)i/(double)sum; 

                            if(mmax<b_p)

                                   mmax=b_p;

                     }

              }

              printf("%.3lf\n",mmax);

       }

       return 0;

}

转载于:https://www.cnblogs.com/lzhitian/archive/2011/08/16/2140078.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值