ACdream 1420 High Speed Trains【Java大数高精度 + 递推】

High Speed Trains

Time Limit: 2000/1000MS (Java/Others)  Memory Limit: 128000/64000KB (Java/Others)
Problem Description

      The kingdom of Flatland has n cities. Recently the king of Flatland visited Japan and was amazed by high speed trains Shinkansens going all around the country. Therefore he decided to build the system of high speed trains in Flatland.

      Each high speed train line will be bidirectional and connect exactly two different cities of Flatland. Although there is actually no need of high speed trains in Flatland, the king ordered that there must be at least one high speed train line from each city of Flatland.
      The minister of transportation told the king that there are several train system satisfying his requirements. The king was amazed by the fact and asked the minister to count the number of possible systems.
      Help the minister to calculate the number of train systems.

Input
      The input file contains one integer number n (2 ≤ n ≤ 100)
Output
      Output one integer number — the number of different train systems that can be arranged in Flatland.
Sample Input
4
Sample Output
41

题意:

给定N个点,保证每个点都至少有一条边与它相连,问可能情况的方案数。2 <= N < = 100

分析:

设ans[i] 表示的是i个点 保证每个点都至少有一条边与它相连,可能情况的方案数。
N个顶点,最多构成N *(N - 1)/ 2条边,每条边有两种状态,即 选 和 不选,那么所有情况的状态数是2^( N *(N - 1)/ 2) ,然后将总状态数分别减去一个顶点无边相连的情况(即ans[N-1] * C(N-1,N)),两个顶点无边相连的情况( 即ans[N-2] * C(N-2,N)),.......,N - 2个顶点无边相连的情况(即ans[2]*C(2,N)), N - 1个顶点无边相连的情况(这种情况特判,为0,因为,不存在仅有一个顶点存在边的情况)N 个顶点无边相连的情况 (即 ans[0]*C(0,N) == 1)。
这样,ans[i] 就可以由ans[j]  (j ∈ [0,N-1] )递推求解出来了。
最后,大数的处理,Java的 BigInteger类 用起来真是方便啊!

代码实现:

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

public class Main {
	public static BigInteger C(int k,int n)
	{
		BigInteger ret = BigInteger.valueOf(1);
		for(int i = n;i >= n-k+1;i--) ret = ret.multiply(BigInteger.valueOf(i));
		for(int i = 2;i <= k;i++) ret = ret.divide(BigInteger.valueOf(i));
		return ret;
	}
	public static void main(String[] args) {
		BigInteger ONE = BigInteger.valueOf(1);
		BigInteger TWO = BigInteger.valueOf(2);
		BigInteger ans[] = new BigInteger[105];
		ans[2] = BigInteger.valueOf(1);
		for(int n = 3;n <= 100;n++) {
			int ENum = n*(n-1)/2;
			ans[n] = TWO.pow(ENum).subtract(ONE);
			for(int i = 2;i < n;i++){
				ans[n] = ans[n].subtract(C(i, n).multiply(ans[i]));
			}
		}
		Scanner cin = new Scanner(System.in);
		while(cin.hasNext()) {
			int N = cin.nextInt();
			System.out.println(ans[N]);
		}
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值