POJ 1018 Communication System

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.

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;
		}
	}
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值