本题是一道DP较为经典的题目,将规模分解变小。
题意非常简单,求n个点的连通图个数。(n<=50)
由于数据量较大,必须使用高精度,代码会显得非常长。这里使用java秒过。
思路:使用n个点构成图全部方案数减去不连通图的个数。
设F[n]表示n个点的不连通图的个数
设a[n]表示n个点的连通图的个数
则F[n]=sum{ c(n-1,k-1) * 2^(c(n-k,2)) * a[k] } 1<=k<=n
//除去第n个点,我们需要从剩余的n-1个点中选取k-1个点,作为第n个点所在的连通分支并且连通分支的总点数位k,剩余的n-k个点任意构图,最后再乘以k个点可以构成的连通图的个数即可。
所以a[n]= 2^(c(n,2))-F[n]
java代码如下:
import java.io.*; import java.util.*; import java.math.*; public class Main { static public BigInteger cal(int n, int k) { BigInteger ret = new BigInteger("1"); for (int i = n; i > n - k; i--) ret = ret.multiply(BigInteger.valueOf(i)); for (int i = 1; i <= k; i++) ret = ret.divide(BigInteger.valueOf(i)); return ret; } static public void main(String[] args) { BigInteger a[] = new BigInteger[51]; a[1] = new BigInteger("1"); for (int i = 2; i <= 50; i++) { a[i] = new BigInteger("0"); for (int j = 1; j < i; j++) { a[i] = a[i].add(a[j].multiply(cal(i - 1, j - 1).multiply(new BigInteger("2").pow((i - j) * (i - j - 1) / 2)))); } a[i] = new BigInteger("2").pow(i * (i - 1) / 2).subtract(a[i]); } Scanner cin = new Scanner(new BufferedInputStream(System.in)); while (cin.hasNext()) { int x = cin.nextInt(); if (x == 0) return; System.out.println(a[x]); } } }
相关推荐
ACM poj1737,Connected Graph
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码
北大POJ1159-Palindrome 解题报告+AC代码
C语言 poj npu 西工大 C语言Poj答案全完整打包,给有需要的朋友
poj 3414解题报告poj 3414解题报告poj 3414解题报告poj 3414解题报告
poj分类poj分类poj分类poj分类
poj 1012解题报告poj 1012解题报告poj 1012解题报告poj 1012解题报告
poj 2329解题报告poj 2329解题报告poj 2329解题报告poj 2329解题报告
北大POJ2002-Squares 解题报告+AC代码
POJ1503解答 POJ1503解答,正确答案(已通过POJ)
poj 1659解题报告poj 1659解题报告poj 1659解题报告poj 1659解题报告
POJ1048,加强版的约瑟夫问题 难度中等
POJ1083的代码,POJ1083的代码,POJ1083的代码
poj 百练 题目分类 poj 百练 题目分类
POJ上的一道题目,自己写的代码,因为想下载别人的, 所以就放上了。
poj 1001答案
POJ2968代码有用,欢迎下载,POJ代码
Poj中一些题目的源代码,里面共有二十多道题目,OI