【推导】【贪心】【高精度】Gym - 101194E - Bet

题意:每个队伍有个赔率pi,如果你往他身上押x元,它赢了,那么你得到x+(1/pi)x元,否则你一分都得不到。问你最多选几支队伍去押,使得存在一种押的方案,不论你押的那几支队伍谁赢,你都能赚得到钱。

设你往第i支队伍上押ai元,不选的视作零元。

首先可以证明,不论你持有多少钱,不影响最后是否有解;是否有解只跟你往各个队伍上押的比例有关。所以不妨设你持有的钱为常数A。

于是有不等式ai*(1+1/pi)>=A,大胆猜测等号成立时,有最极限的解。于是ai=A/(1+1/pi)。

也就是你往第i支队伍身上押的钱数,占你的总钱数的1/(1+1/pi)。

于是把所有队伍按照1/(1+1/pi)从小到大排序,依次尽量选择即可。

注意!由于精度爆炸,所以要用高精度做分数运算。

import java.util.*;
import java.io.*;
import java.math.*;

public class Main{
	public static void main(String[] argc){
		BigInteger[] A=new BigInteger[105];
		BigInteger[] B=new BigInteger[105];
		double[] C=new double[105];
		int[] vis=new int[105];
		String S;
		char[] s=new char[105];
		Scanner sc = new Scanner (new BufferedInputStream(System.in));
		int T=sc.nextInt();
		for(int zu=1;zu<=T;++zu){
			System.out.printf("Case #%d: ",zu);
			int n=sc.nextInt();
			for(int i=1;i<=n;++i){
				long tA=0,tB=0;
				S=sc.next();
				int len=S.length();
				s=S.toCharArray();
				int colon=0;
				for(int j=0;j<len;++j){
					if(s[j]==':'){
						colon=j;
						break;
					}
				}
				int pos1=colon-1;
				for(int j=0;j<colon;++j){
					if(s[j]=='.'){
						pos1=j;
					}
					else{
						tA=tA*10+s[j]-'0';
					}
				}
				int pos2=len-1;
				for(int j=colon+1;j<len;++j){
					if(s[j]=='.'){
						pos2=j;
					}
					else{
						tB=tB*10+s[j]-'0';
					}
				}
				for(int j=1;j<=colon-pos1-len+pos2;++j){
					tB*=10l;
				}
				for(int j=1;j<=len-pos2-colon+pos1;++j){
					tA*=10l;
				}
				A[i]=BigInteger.valueOf(tA);
				B[i]=A[i].add(BigInteger.valueOf(tB));
				C[i]=(double)tA/((double)tA+(double)tB);
			}
			BigInteger sumA=BigInteger.ZERO,sumB=BigInteger.ONE;
			for(int i=1;i<=n;++i){
				vis[i]=0;
			}
			int flag=0;
			for(int i=1;i<=n;++i){
				double minn=2000000000.0;
				int id=0;
				for(int j=1;j<=n;++j)if(vis[j]==0){
					if(C[j]<minn){
						minn=C[j];
						id=j;
					}
				}
				vis[id]=1;
				sumA=sumA.multiply(B[id]).add(sumB.multiply(A[id]));
				sumB=sumB.multiply(B[id]);
				if(sumA.compareTo(sumB)>=0){
					System.out.println(i-1);
					flag=1;
					break;
				}
			}
			if(flag==0){
				System.out.println(n);
			}
//			for(int i=1;i<=n;++i){
//				System.out.print(A[i]);
//				System.out.printf(" ");
//				System.out.println(B[i]);
//			}
		}
		sc.close();
    }
}
posted @ 2017-10-14 17:35  AutSky_JadeK  阅读(249)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト