Problem:
Unequal Dice

Time Limit: 8 sec / Memory Limit: 64 MB

B: 不揃いなサイコロ

パチンコや競馬などの賭け事にお金を使いすぎて，借金まみれになったあなたは，
T愛グループの地下監獄に収容されてしまった．
ここであなたは，借金を返すまで奴隷のように働かなくてはならない．

またこの監獄にはあなたと同じ境遇の人が多く収容されているので，
いくつかの班に分けられている．
ある班では，サイコロを3つ転がしてお椀にいれて楽しむ習慣がある．
最近，そこの班長が大変な目にあったとかいう話を聞いたが，あなたに直接関係はない．

あなたの所属する班ではひとつのサイコロを振って楽しむ習慣がある．
ルールは，サイコロを振って目の大きな値を出せば勝ちという簡単なものである．
ただ特殊なこととしては，用いられるサイコロのある面が出る確率が，同様に確からしくないということである．
またサイコロも種類が多く，10面体のものから100面体のものとさまざまに用意されている．
さらに何も値の書かれていない面まである．
何の値も書かれていない面が出たときは，再度振りなおしをする．

このゲームを仕切っている班長から，あらかじめ振っても良いサイコロをいくつか提示されたのだが，どれを使っても勝てる気がしない時がある．

そこで，与えられたサイコロの内，班長が使うサイコロで出る値の期待値より高いサイコロがあるのかどうか調べたい．
期待値が高いとは班長のサイコロより，0.0000001より大きい時を指す．

Input

入力は以下の形式で与えられる．

t
n1 m1
v1 r1
...
vm1 rm1
n2 m2
...
nt mt
v1 r1
...
vmt rmt
p q
v1 r1
...
vq rq

入力の形式に含まれる各変数の意味と制約は以下の通りである．

t は与えられるサイコロの数 t (0 < t <=10)

n は何面体であるのかを表す整数 (4 <= n <= 100)

m は数値の振られている面の数 (0 < m <= n)

vi は面に振られている数値 (0<= v <= 100)

ri はその面が出る確率 (0 < r <= 1.0)

r1 + r2 + ... + rm <= 1.0は保証される．

また ri は小数第10位まで与えられることがある．

p は班長の使うサイコロが何面体であるかを表す整数

q は班長の使うサイコロに数値の振られている面の数

Output

班長の使うサイコロよりも期待値の高いサイコロがあればYES，そうでなければNOを出力せよ．

Sample Input 1

2
4 2
4 0.4000000
3 0.5000000
4 1
5 0.3333333
5 3
5 0.7777777
4 0.1111111
2 0.0001111

Sample Output 1

YES

Sample Input 2

2
4 2
4 0.5000000
3 0.4000000
4 1
5 0.3333333
5 3
8 0.7777777
4 0.1111111
2 0.0001111

Sample Output 2

NO

Solution in JAVA (judge verdict: Accepted)

import java.util.Scanner;

public class Main{
	public static double expect(double[][] x){
		double sum = 0;
		for(int i = 0; i < x.length; i++){
			sum += x[i][1];
		}
		double result = 0;
		for(int i = 0; i < x.length; i++){
			result += x[i][0]*x[i][1]/sum;
		}
		return result;
	}
	
	public static void main(String[] args){
		Scanner stdIn = new Scanner(System.in);
		
		int T = stdIn.nextInt();
		double max = 0;
		for(int i = 0; i < T; i++){
			int n = stdIn.nextInt(), m = stdIn.nextInt();
			double[][] p = new double[m][2];
			for(int j = 0; j < m; j++){
				p[j][0] = stdIn.nextDouble();
				p[j][1] = stdIn.nextDouble();
			}
			double key = expect(p);
			if( key > max ){
				max = key;
			}
		}
		int n = stdIn.nextInt(), m = stdIn.nextInt();
		double[][] p = new double[m][2];
		for(int j = 0; j < m; j++){
			p[j][0] = stdIn.nextDouble();
			p[j][1] = stdIn.nextDouble();
		}
		double key = expect(p);
		if( max-key >= 0.0000001 ){
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}
}