POJ  1018  Communication System

本文深入解析了POJ 1018 Communication System问题,详细阐述了如何利用动态规划(DP)、贪心算法和枚举技巧解决通信系统设计中最大化带宽与成本比值的问题。通过实例分析,揭示了看似简单的题目背后隐藏的复杂细节和算法应用,为读者提供了深入理解及解决类似问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Poj_1018_Communication System

关键词:dp 贪心 枚举

题目描述:Communication System

Time Limit: 1000MS

 

Memory Limit: 10000K

Total Submissions: 8824

 

Accepted: 3095

Description

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.

Input

The first line of the input file contains a single integer t (1 t10), 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 (1n100), the number of devices in the communication system, followed by n lines in the following format: the i-th line (1in) starts with mi (1mi100), the number of manufacturers for the i-th device, followed by mi pairs of positive integers in the same line, each indicating the bandwidth and the price of the device respectively, corresponding to a manufacturer.

Output

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

Sample Input

1 3

3 100 25 150 35 80 25

2 120 80 155 40

2 100 100 120 110

Sample Output

0.649

这题还不会写,但是还是先贴上大牛(大牛貌似语文不是太好,错别字就让我改了半天POJ <wbr> <wbr>1018 <wbr> <wbr>Communication <wbr>System)的吧,省的以后找不到了

题目分析:本题一看一位很水,没想到还有这么多细节啊!吸取教训。仔细一看想用dp,找不到什么子结构,贪心感觉有不太对。最后感觉有点像二分的枚举。题目意思大概就是有ndevices,每个都需要一个bandwidth,而这个会有很多商家提供,价格不同,现在在n个中,每个选一个,但是着n个中选B最小的,而所有选的price和最小,即是B/p最大。

算法:就是找到所有组中最小的且是所有组中最小的B,和每组中最大的B且是所有组中最小的,然后从最小到最大枚举,每次选取大于Bp最小的,然后比较求出最大的B/P

思考:水题不水!每一个题都应该认真对待。总结-做题-再总结。

代码:

#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));

              high=32767;

              low=32767;

              scanf("%d",&m);

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

              {

                     min=32767;

                     max=0;

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

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

                     {

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

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

                            flag[b[i][j]]=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])

                     {

                            sum=0;

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

                            {

                                   min=32767;

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

                                   {

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

                                          {

                                                 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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值