acm pku 1018 Communication System的算法改進

Communication System

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 ≤ 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 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

Source

Tehran 2002, First Iran Nationwide Internet Programming Contest

      

       這道題目的主要解決方案是剪枝搜索方法,在網上已經有很多實現了,例如:http://blog.chinaunix.net/u3/102624/showart_2037983.html 在這裏要說的作者想說的是,在網絡已經出現的方法基礎上,還可以對算法進行進一步的優化。

       一般地,我們記錄下所有設備的帶寬的最大值和最小值,並且,取:

       downB: 所有設備的最小值帶寬的最小值;

upB:   所有設備的最大值帶寬的最大值;

並搜索,[downB, upB]間的所有帶寬,來求得最大的B/P; 作者所看到的,別人的算法,在這裏直接進行了搜索,雖然也能通過,但是這裏的確可以進一步進行優化,因爲並不是[downB, upB]之間的所有整數所對應的帶寬都存在於具體的設備中,即存在某些整數S,且S屬於[downB, upB],但卻不屬於輸入的帶寬值,因此,在進行搜索的時候,這些值完全可以跳過,以達到節省時間的目的。加入一布爾變量bindex[INFINIT],用於表示某個帶寬是否在設備中出現,若其出現,則對其搜索,若其不出現,則跳過搜索。具體的代碼如下:

#include "iostream"

//#include "iomanip"

#include "stdio.h"

using namespace std;

const int INFINIT = 342289;

 

int main()

{

       int t, n, mi[100], P, downB, upB, minB, maxB, minP;

       int ibd[100][100], ipr[100][100];

       int i, j, k;

       bool bindex[INFINIT];

       double result;

 

 

       cin >> t;

       while(t --)

       {    

              downB = INFINIT;

              upB = INFINIT;

              memset(bindex, 0, sizeof(bool)*INFINIT);

              result = 0;

 

              cin >> n;

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

              {

                     minB = INFINIT;

                     maxB = -INFINIT;

                     cin >> mi[i];

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

                     {

                            cin >> ibd[i][j] >> ipr[i][j];

                            bindex[ibd[i][j]] = true;

                            if(minB > ibd[i][j])

                            {

                                   minB = ibd[i][j];

                            }

                            if(maxB < ibd[i][j])

                            {

                                   maxB = ibd[i][j];

                            }

                     }

                     if(downB > minB)

                     {

                            downB = minB;

                     }

                     if(upB > maxB)

                     {

                            upB = maxB;

                     }

              }

 

              for(k = downB; k <= upB; k ++)

              {

                     if(bindex[k])

                     {

                            P = 0;

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

                            {

                                   minP = INFINIT;

                                   //for(j = 1; j < mi[i]; j ++)

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

                                   {

                                          if(ibd[i][j] >= k && minP > ipr[i][j])

                                          {

                                                 minP = ipr[i][j];

                                          }

                                   }

                                   P += minP;

                            }

                            if(result < ((double)k)/((double)P))

                            {

                                   result = ((double)k)/((double)P);

                            }

                     }

              }

              printf("%.3f/n", result);

       }

       return 0;

}

 

提交結果:

Problem: 1018

 

User: uestcshe

Memory: 612K

 

Time: 63MS

Language: C++

 

Result: Accepted

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章