Communication System
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 17903 | Accepted: 6318 |
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.
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
题目分析:首先,我们可以去掉那些带宽比别人小,而价格又比别人高的那些产品。然后,由于整个系统的带宽是由系统中最小的带宽决定的,因此对于任意一个方案,我们要想提高它的带宽,只需要,而且必须要增加带宽最窄的那些零部件的带宽。本来我们要搜索所有的可能方案,但是由于我们上面所说的这些原因,我们只需要搜索其中一部分方案就行了,而另外的一些方案不用搜索就知道不是最优的。我们的搜索就是每次对于一个已有方案,增加“瓶颈”部分的带宽。要实现这样的搜索,还必须先把每一类产品按照带宽从低到高排序。代码如下:
package poj1018;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
for(int t=in.nextInt();t>0;t--){
int n=in.nextInt();
ArrayList<List<Product>> products=new ArrayList<List<Product>>();
for(int i=0;i<n;i++){
products.add(new ArrayList<Product>());
int mi=in.nextInt();
//input one line of data
for(int j=0;j<mi;j++){
int bandwidth=in.nextInt();
int price=in.nextInt();
boolean canInsert=true;
for(int k=0;k<products.get(i).size();k++){
if(products.get(i).get(k).bandwidth>=bandwidth&&products.get(i).get(k).price<=price){
canInsert=false;
break;
}else if(products.get(i).get(k).bandwidth<=bandwidth&&products.get(i).get(k).price>=price){
products.get(i).remove(k);
k--;
}
}
if(canInsert){
products.get(i).add(new Product(bandwidth,price));
}
}
//sort this line of data
for(int j=0;j<products.get(i).size()-1;j++){
for(int k=0;k<products.get(i).size()-1-j;k++){
if(products.get(i).get(k).bandwidth>products.get(i).get(k+1).bandwidth){
Product tmp=products.get(i).get(k);
products.get(i).set(k, products.get(i).get(k+1));
products.get(i).set(k+1, tmp);
}
}
}
}// data input over
int[]state =new int[n];
double maximum_rate=value(state, products);
while(hasNext(state, products)){
next(state, products);
double temp_rate=value(state, products);
if(temp_rate>maximum_rate){
maximum_rate=temp_rate;
}
}
System.out.printf("%.3f\n",maximum_rate);
}
}
static int minimumBandwidth(int[] state, List<List<Product>> products){
int result=Integer.MAX_VALUE;
for(int i=0;i<state.length;i++){
if(products.get(i).get(state[i]).bandwidth<result){
result=products.get(i).get(state[i]).bandwidth;
}
}
return result;
}
static double value(int[] state, List<List<Product>> products){
int minimum_bandwidth=minimumBandwidth(state, products);
int sum_price=0;
for(int i=0;i<state.length;i++){
sum_price+=products.get(i).get(state[i]).price;
}
/*System.out.println("state : ");
for(int i=0;i<state.length;i++){
System.out.print(state[i]+"\t");
}System.out.println();
System.out.println("rate : "+(double)sum_price/minimum_bandwidth);
*/
return (double)minimum_bandwidth/sum_price;
}
static boolean hasNext(int[] state, List<List<Product>> products){
int minimum_bandwidth=minimumBandwidth(state, products);
for(int i=0;i<state.length;i++){
if(products.get(i).get(state[i]).bandwidth==minimum_bandwidth&&state[i]==products.get(i).size()-1){
return false;
}
}
return true;
}
static void next(int[] state, List<List<Product>> products){
int minimum_bandwidth=minimumBandwidth(state, products);
for(int i=0;i<state.length;i++){
if(products.get(i).get(state[i]).bandwidth==minimum_bandwidth){
state[i]++;
}
}
}
static class Product{
int bandwidth;
int price;
Product(){
this.bandwidth=0;
this.price=0;
}
Product(int b, int p){
this.bandwidth=b;
this.price=p;
}
}
}