POJ 1306 - Combinations - BigInteger or DP

 

POJ 1306 - Combinations

描述
当N和/或M变得非常大时,计算N个事物一次可以取M的方式的精确值可能是一个巨大的挑战。
挑战是竞赛的内容。因此,您只需进行如下计算:
给定:5 <= N <= 100; 5 <= M <= 100; M <= N
计算精确值:C = N! / (N-M)!M!

您可以假设C的最终值将适合32位Pascal LongInt或C long。
请注意,100!精确值是:
93,326,215,443,944,152,681,699,238,856,266,700,490,715,968,264,381,621, 468,592,963,895,217,599,993,229,915,608,941,463,976,156,518,286,253, 697,920,827,223,758,251,185,210,916,864,000,000,000,000,000,000,000,000

输入
序的输入将是一行或多行,每行包含零个或多个前导空格、一个N值、一个或多个空格和一个M值。
输入文件的最后一行将包含两个值都等于零的伪N,M对。读取此行时,程序应终止。

输出
此程序的输出格式应为:
N一次取M的东西就是C。

Sample Input
100 6
20 5
18 6
0 0

Sample Output
100 things taken 6 at a time is 1192052400 exactly.
20 things taken 5 at a time is 15504 exactly.
18 things taken 6 at a time is 18564 exactly.

 

思路:
方法1: 公式已给出,直接计算就好,阶乘数据较大,long也会超出范围,可使用BigInteger
方法2: 使用DP,声明dp数组,保存1~100的阶乘,第i个元素表示i的阶乘,计算结果时,取dp[N]/dp[N-M]/dp[M];

 

package basic_data_structure;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

/**
 * 
 * @author XA-GDD
 * 
 * 思路:
 * 方法1: 公式已给出,直接计算就好,阶乘数据较大,long也会超出范围,可使用BigInteger
 * 方法2: 使用DP,声明dp数组,保存1~100的阶乘,第i个元素表示i的阶乘,计算结果时,取dp[N]/dp[N-M]/dp[M];
 *
 */
public class E_Combinations {

	static BigInteger NFactorial,MFactorial,NMFactorial,C ;
	static int N,M;
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
	
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;  
        StringTokenizer st;
		while((str = br.readLine()) != null) {
			st = new StringTokenizer(str);
			N = Integer.parseInt(st.nextToken());
			M = Integer.parseInt(st.nextToken());
			if(N==0 && M==0)	break;
			
			NFactorial = new BigInteger("1");
			MFactorial = new BigInteger("1");
			NMFactorial = new BigInteger("1");
			C = new BigInteger("1");
			
			Factorial fact = new Factorial(N,M);
			NFactorial = fact.getNFactorial();
			MFactorial = fact.getMFactorial();
			NMFactorial = fact.getNMFactorial();
			
			C = NFactorial.divide((MFactorial).multiply(NMFactorial));
			System.out.println(N+" things taken "+M+" at a time is "+C+" exactly.");
			
		}
		
	}

}

class Factorial{
	int n;
	int m;
	int subtractNM;
	BigInteger nFactorial;
	BigInteger mFactorial;
	BigInteger subtractNMFactorial;
	Factorial(int n,int m) {
		this.n = n;
		this.m = m;
		this.subtractNM = n-m;
		nFactorial = new BigInteger("1");
		mFactorial = new BigInteger("1");
		subtractNMFactorial = new BigInteger("1");
	}
	public BigInteger getNFactorial() {
		for(int i=n;i>=1;i--) {	
			nFactorial=nFactorial.multiply(BigInteger.valueOf(i));
		}
		return nFactorial;
	}
	
	public BigInteger getMFactorial() {
		for(int i=m;i>=1;i--) {	
			mFactorial=mFactorial.multiply(BigInteger.valueOf(i));
		}
		return mFactorial;
	}
	
	public BigInteger getNMFactorial() {
		for(int i=subtractNM;i>=1;i--) {	
			subtractNMFactorial=subtractNMFactorial.multiply(BigInteger.valueOf(i));
		}
		return subtractNMFactorial;
	}
	
}

  

posted @ 2021-10-10 09:43  晓暮云  阅读(49)  评论(0)    收藏  举报