递推 ACdream1420 High Speed Trains

传送门:点击打开链接

题意:n个点,每个点至少被一条边覆盖,不存在自环和重边。问有多少种情况

一个非常有意思的递推,其实可以利用容斥的思想去考虑这道题目

设F[n]表示为n个点的情况数,那么最多会存在n*(n-1)/2条边,这些边中,每条边都是可有可无。如果不考虑不满足条件的情况(也就是有的点没有被边覆盖的情况),可能的情况数为pow(2,n*(n-1)/2),也就是考虑每一条边是否存在

那么对于答案而言,不能有点没有被覆盖,接下来我们就来枚举点被边覆盖的个数,设为k

当有k个点被覆盖了,这k个点的情况数就是F[k],那么这k个点分别是哪k个,需要组合数C(n,k),所以对于k个点被覆盖时,不满足条件的总类数就是F[k]*C(n,k)

k可以从1枚举到n-1,然后还要考虑一个特殊情况,就是没有一个点被边覆盖,这只有1种情况。

综上所述,答案是F[n]=pow(2,n*(n-1)/2)-segma(F[k]*C(n,k))其中1<=k<=n-1

import java.util.Scanner;
import java.math.*;

public class Main {
	static final int MX = 100 + 5;

	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);

		BigInteger zero = BigInteger.valueOf(0);
		BigInteger one = BigInteger.valueOf(1);
		BigInteger two = BigInteger.valueOf(2);

		BigInteger[][] C = new BigInteger[MX][MX];
		C[0][0] = one;
		for (int i = 1; i < MX; i++) {
			C[i][0] = C[i][i] = one;
			for (int j = 1; j < i; j++) {
				C[i][j] = C[i - 1][j - 1].add(C[i - 1][j]);
			}
		}

		BigInteger f[] = new BigInteger[MX];
		f[1] = one;
		f[2] = one;
		for (int i = 3; i < MX; i++) {
			f[i] = two.pow(i * (i - 1) / 2).subtract(one);
			for (int k = 2; k <= i - 1; k++) {
				f[i] = f[i].subtract(C[i][k].multiply(f[k]));
			}
		}

		while (cin.hasNext()) {
			int n = cin.nextInt();
			System.out.println(f[n]);
		}
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-15 01:10:57

递推 ACdream1420 High Speed Trains的相关文章

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

Code Force 429B Working out【递推dp】

Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and mcolumns. Let number a[i][j] represents the calories burned by performing workout at the

codeforces Gym 100338H High Speed Trains

递推就好了,用二项式定理算出所有连边的方案数,减去不合法的方案, 每次选出一个孤立点,那么对应方案数就是上次的答案. 枚举选几个孤立点和选哪些,选到n-1个点的时候相当于都不选,只减1. 要用到高精度,直接开100*100的组合数数组会MLE,用滚动数组优化一下就好了. 不会java,python太伤了 #include<bits/stdc++.h> using namespace std; const int MAXN = 20000; struct bign { int len, s[MA

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

hdu 1267 递推

下沙的沙子有几粒? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4326    Accepted Submission(s): 2268 Problem Description 2005年11月份,我们学校参加了ACM/ICPC 亚洲赛区成都站的比赛,在这里,我们获得了历史性的突破,尽管只是一枚铜牌,但获奖那一刻的激动,也许将永远铭刻

hdu 2067(递推或卡特兰数【待补充】)

//解法一:递推#include<iostream> using namespace std; long long d[36][36]; int main() { for(int i=1;i<=35;i++) { d[0][i]=1; } for(int i=1;i<=35;i++) for(int j=i;j<=35;j++) { if(i==j) d[i][j]=d[i-1][j]; else d[i][j]=d[i-1][j]+d[i][j-1]; } int n; i

NPU 2015年陕西省程序设计竞赛网络预赛(正式赛)F题 和谐的比赛(递推 ||卡特兰数(转化成01字符串))

Description 今天西工大举办了一场比赛总共有m+n人,但是有m人比较懒没带电脑,另外的n个人带了电脑.不幸的是,今天机房的电脑全坏了只能用带的电脑,一台电脑最多两人公用,确保n>=m.但是大家来的时间不同,随机次序来机房,带电脑的人直接准备比赛而没带电脑的人需要向带电脑并还没和别人公用的人求助(当然会答应).但是,如果不存在带电脑并还没和别人公用的人,那他就要等了,等是很让人头疼的,这就不和谐了,当然假如没有这样的情况发生比赛是很和谐的. Input 输入多组数据,每组数据只有一行m(

矩阵经典题目七:Warcraft III 守望者的烦恼(矩阵加速递推)

https://www.vijos.org/p/1067 很容易推出递推式f[n] = f[n-1]+f[n-2]+......+f[n-k]. 构造矩阵的方法:构造一个k*k的矩阵,其中右上角的(k-1)*(k-1)的矩阵是单位矩阵,第k行的每个数分别对应f[n-1],f[n-2],,f[n-k]的系数.然后构造一个k*1的矩阵,它的第i行代表f[i],是经过直接递推得到的.设ans[][]是第一个矩阵的n-k次幂乘上第二个矩阵,f[n]就是ans[k][1]. 注意:用__int64 #in

uva 1478 - Delta Wave(递推+大数+卡特兰数+组合数学)

题目链接:uva 1478 - Delta Wave 题目大意:对于每个位置来说,可以向上,水平,向下,坐标不能位负,每次上下移动最多为1, 给定n问说有多少种不同的图.结果对10100取模. 解题思路:因为最后都要落回y=0的位置,所以上升的次数和下降的次数是相同的,并且上升下降的关系满足出栈入栈的关系.即卡特兰数. 所以每次枚举i,表示有i个上升,i个下降,用组合数学枚举出位置,然后累加求和. C(2?in)?f(i)=C(2?i?2n)?f(i?1)?(n?2?i+1)?(n?2?i+2)