【Java】【高精度】【组合数】【递推】poj1737 Connected Graph

http://blog.csdn.net/sdj222555/article/details/12453629

这个递推可以说是非常巧妙了。

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

public class Main{
	static BigInteger[] g=new BigInteger[60];
	static BigInteger[] f=new BigInteger[60];
	static BigInteger[] pow_2=new BigInteger[2510];
	static long[][] C=new long[60][60];
	public static void main(String[] argc){
		C[0][0]=1l;
	    for(int i=1;i<=50;++i){
	        C[i][0]=C[i][i]=1l;
	        for(int j=1;j<i;++j){
	            C[i][j]=C[i-1][j]+C[i-1][j-1];
	        }
	    }

	    pow_2[0]=BigInteger.ONE;
	    for(int i=1;i<=2500;++i){
	    	pow_2[i]=pow_2[i-1].multiply(BigInteger.valueOf(2l));
	    }

		g[0]=BigInteger.ONE;
		for(int i=1;i<=50;++i){
			g[i]=BigInteger.ZERO;
			for(int k=1;k<i;++k){
				g[i]=g[i].add(((BigInteger.valueOf(C[i-1][k-1])).multiply(f[k])).multiply(pow_2[(i-k)*(i-k-1)/2]));
			}
			f[i]=pow_2[i*(i-1)/2].subtract(g[i]);
		}

		Scanner sc = new Scanner (new BufferedInputStream(System.in));
		while(true){
			int n=sc.nextInt();
			if(n==0){
				break;
			}
			System.out.println(f[n]);
		}
		sc.close();
    }
}
时间: 2024-07-30 13:47:02

【Java】【高精度】【组合数】【递推】poj1737 Connected Graph的相关文章

组合数递推算法

主要式子:C(n,k)=C(n-1,k-1)+C(n-1,k),C(n,k)表示从n个物品中挑选k个物品的所有组合数. 1 #include<stdio.h> 2 #include<string.h> 3 #define N 10 4 int c[N][N]; 5 void init() 6 { 7 memset(c,0,sizeof(c)); 8 for(int i=0;i<=N;i++) 9 { 10 c[i][0]=1; 11 c[i][i]=1; 12 for(int

poj1737 Connected Graph

题目意思就不赘述了. 这是一个计数问题,一开始考虑如何去重却没有想到可行的办法. 原因是只考虑计数连通的方案数是困难的. 设n阶图连通的方案数为f(n),不连通的方案数为g(n) = 2^(2, n) - f(n). 不连通的图存在多于1个的连通分量,而每个连通分量是连通的,这是本题的切入点. 考虑点1所在的连通分量,设其节点数为k(< n),那么所求即等价于计数剩余(n - k)个节点连通或不连通方案数. 可以枚举从1到n - 1枚举k,如此有g(n) = sigma((k - 1, n -

$Poj1737\ Connected\ Graph$ 计数类$DP$

AcWing Description 求$N$个节点的无向连通图有多少个,节点有标号,编号为$1~N$. $1<=N<=50$ Sol 在计数类$DP$中,通常要把一个问题划分成若干个子问题,以便于执行递推. 一个连通图不容易划分,而一个不连通的无向图则很容易划分成结点更少的两部分.所以我们把问题转化成用$N$个点的无向图总个数减去$N$个点的不连通无向图的个数. $N$个点的无向图总个数显然是$2^{N*(N-1)/2}$,还是简单说下叭,就是$N$个点连成完全图的边数显然是$N*(N-1)

Codeforces 631 D. Dreamoon Likes Sequences 位运算^ 组合数 递推

https://codeforces.com/contest/1330/problem/D 给出d,m, 找到一个a数组,满足以下要求: a数组的长度为n,n≥1; 1≤a1<a2<?<an≤d: 定义一个数组b:b1=a1, ∀i>1,bi=bi−1⊕ai ,并且b1<b2<?<bn−1<bn: 求满足条件的a数组的个数并模m: 人话:求一个a数组满足递增,并且异或前缀和也递增 ,求出a数组个数mod m. 太菜了,不会,看了很多题解才会的,这里总结一下:

java递归和递推应用的小程序

1.方法重载 通过对不同函数的调用,得到不同类型的返回值: 方法的重载: *方法名相同 *靠参数类型.参数类型顺序.参数个数为判断条件区分调用 *返回值不作为判断条件 2.杨辉三角代码: 通过递推关系完成对杨辉三角形的输出. 3.回文串的判断: 代码: 运用递归关系,通过对被本身函数的调用完成判断是否为回文的过程. 4.产生随机数的代码: for ( long i = 1; i <= 1000; i++ ) {                 //1000个随机数 value = 1 + (in

机房测试5:silhouette(组合数+递推)

题目: 分析: (这道题是真的难)(声明: 在这位大佬的题解下多做了说明,图片来源也是他的博客.) 首先我们要发现一些小规律: 1.将A和B排序之后并不影响答案 证明:不管哪一列排序放到了哪里,那一列的最大值都应该是Ai. 2.A的最大一定等于B的最大: 很显然,如果不等于,那么最大值放在哪里都不合法. 3.将A和B数组按从小到大的顺序排序后,会变成这种矩形: 定义f[ i ]为至少有i行不满足,定义至少的原因:两两行之间不会受影响 显然最后我们要求的是恰好有0行不满足,即至少有0行不满足-至少

hdu2068 RPG的错排 组合数/递推

1 #include<stdio.h> 2 long long arr[21]; 3 long long c(int a,int b) 4 { 5 long long i,sum=1,j; 6 for (i=a,j=1;i>=a-b+1,j<=b;i--,j++) sum=sum*i/j; 7 return sum; 8 } 9 void func() 10 { 11 int i; 12 arr[1]=0;arr[2]=1; 13 for(i=3;i<=26;i++) 14

UVa 10253 (组合数 递推) Series-Parallel Networks

<训练之南>上的例题难度真心不小,勉强能看懂解析,其思路实在是意想不到. 题目虽然说得千奇百怪,但最终还是要转化成我们熟悉的东西. 经过书上的神分析,最终将所求变为: 共n个叶子,每个非叶节点至少有两个子节点的 树的个数f(n).最终输出2 × f(n) 首先可以枚举一下根节点的子树的叶子个数,对于有i个叶子的子树,共有f(i)种, 设d(i, j)表示每棵子树最多有i个叶节点,一共有j个叶节点的方案数. 所求答案为d(n-1, n) 假设恰好有i个叶子的子树有p棵,因为每个子树互相独立,所以

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

High Speed Trains Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) 链接:http://acdream.info/problem?pid=1420 Problem Description The kingdom of Flatland has n cities. Recently the king of Flatland visited Japan and was a