ACM: 三分法 poj 1018  (学习到三…

来源:互联网 发布:淘宝网左轮吉他直播 编辑:程序博客网 时间:2024/05/22 06:43
Communication System
Description
We have received anorder from Pizoor Communications Inc. for a special communicationsystem. The system consists of several devices. For each device, weare free to choose from several manufacturers. Same devices fromtwo manufacturers differ in their maximum bandwidths andprices.
By overall bandwidth (B) we mean the minimum of the bandwidths ofthe chosen devices in the communication system and the total price(P) is the sum of the prices of all chosen devices. Our goal is tochoose a manufacturer for each device to maximize B/P.

Input

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

Output

Your program shouldproduce a single line for each test case containing a single numberwhich is the maximum possible B/P for the test case. Round thenumbers 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

题意: 不同设备中各取出一种设备,使得这些设备带宽的最小值和它们价值的总和的比最大.

解题思路:
         1. 网上学习的三分法.

代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
#define MAX 105
const int INF = (1<<29);

int n;
int b[MAX][MAX], price[MAX][MAX], count[MAX];
int all[MAX*MAX];
int num;

int cmp(const void *a, const void *b)
{
    return *(int*)a - *(int*)b;
}

inline int min(int a,int b)
  
    return a < b ? a : b;
}

inline double max(double a, double b)
{
    return a > b ? a : b;
}

double solve(int x)
{
    double sum = 0;
    for(int i = 1; i <= n; ++i)
    {
        int mint = INF;
        for(int j = 1; j <= count[i]; ++j)
        {
            if(all[x] <= b[i][j])
                mint = min(mint, price[i][j]);
        }
        sum += mint;
    }
    return all[x] / sum;
}

int main()
{
//    freopen("input.txt","r",stdin);
    int caseNum;
    scanf("%d",&caseNum);
    while(caseNum--)
    {
        scanf("%d",&n);
        num = 1;
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d",&count[i]);
            for(int j = 1; j <= count[i]; ++j)
            {
                scanf("%d %d",&b[i][j], &price[i][j]);
                all[num++] = b[i][j];
            }
        }
        qsort(all+1,num,sizeof(all[0]),cmp);
       
        int left = 1, right = num;
        int mid1, mid2;
        while(left+1 < right)
        {
            mid1 = (left+right)/2;
            mid2 = (mid1+right)/2;
            double temp1 = solve(mid1);
            double temp2 = solve(mid2);
            if(temp1 < temp2) left = mid1;
            else right = mid2;
        }
        double result = max(solve(left), solve(right));
        printf("%.3f\n",result);
    }
    return 0;
}
0 0
原创粉丝点击