博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ACM学习历程—NPU1045 2015年陕西省程序设计竞赛网络预赛(热身赛)C题 Graph Theory(递推 && 组合数学 && 大数)...
阅读量:4629 次
发布时间:2019-06-09

本文共 2619 字,大约阅读时间需要 8 分钟。

Description

In graph theory, a matching or independent edge set in a graph G = (V , E) is a set of edges ME such that no two edges in the matching M share a common vertex.

The Nobel Prize in XiXiHaHa was awarded to Jerryxf team, amongst other things, their algorithm for finding a matching satisfying certain criteria in a bipartite graph. Since you have also heard that matchings in cycle graphs have applications in chemistry your thoughts centre around a plan for a beautiful future where your Christmas shopping is more luxurious than ever!

The cycle graph, Cn, n3, is a simple undirected graph, on vertex set 1,……, n, with edge set E(Cn) = {

{a , b}  |  |a-b| ≡ 1 mod mod n }. It is 2-regular, and contains n edges. The graphs C3, C4, C5, and C6 are depicted in Figure 1.

 

Your first step towards Nobel Prize fame is to be able to compute the number of matchings in the cycle graph Cn. In Figure 2 the seven matchings of the graph C4 are depicted.

 

 

 

 

Figure 2: The matchings of C4. The edges that are part of the respective matching are coloured green, while the edges left out of the matching are dashed. M1 =  ,  M2 = {{2 ,1}} , M3={{3 , 2}} ,  M4 ={{4 , 3}}, M5 = {{1 , 4}}, M6 = {{2 , 1},{4 , 3}}, and M7 = {{3 , 2},{1 , 4}}

 

Input

For each test case, you get a single line containing one positive integer: n, with 3n10000.

Output

For each test case, a row containing the number of matchings in Cn.

Sample Input

34100

Sample Output

47792070839848372253127

 

题目意思就是在一个环上放线段,线段不能相邻,求放法数。

这是一个典型的组合类型问题,不过圆形的排列不太好搞。

我们考虑直链型的:对于直链型的,不妨设f(n)表示以n结尾的直链型的方法数。

考虑n处不放线段,那么去掉n,剩下(n-1)个就变成了子问题f(n-1);

考虑n处放线段,那么n-1处必然不能放,于是剩下的(n-2)个就变成了子问题f(n-2);

于是对于直链的:f(n) = f(n-1) + f(n-2),正好是一个费波拉契数列。

 

于是对于圆形排列的就好考虑了:不妨设s(n)表示n个的圆形排列的数目。

考虑第n个不放线段,那么剩余的(n-1)变可以从第n个那处展开成直链的f(n-1);

考虑第n个放线段,那么第1个和第n-1个必然不能放,那么剩下n-3个便是直链的f(n-3)

于是s(n) = f(n-1) + f(n-3),理论上到此处变可以求s(n)了,首先对f(n)将前10000项打表,然后就可以求任意s(n)(注意f(0) = 1, f(1) = 2)

 

不过由于s(n) = f(n-1) + f(n-3), 自然s(n) = s(n-1) + s(n-2),其本身也是费波拉契数列。

 

由于此处需要考虑大数,故采用了Java的大数类。

 

代码:

import java.math.BigInteger;import java.util.Scanner;public class Main{    public static void main(String args[])    {        BigInteger f[] = new BigInteger[10001];        f[0] = new BigInteger("1");        f[1] = new BigInteger("2");        for (int i = 2; i <= 10000; ++i)        {            f[i] = new BigInteger("0");            f[i] = f[i-1].add(f[i-2]);        }        Scanner input = new Scanner(System.in);        int n;        while (input.hasNext())        {            n = input.nextInt();            System.out.println(f[n-1].add(f[n-3]));        }    }}

 

转载于:https://www.cnblogs.com/andyqsmart/p/4509312.html

你可能感兴趣的文章
hdu 1501 DFS+记忆化搜索
查看>>
试说移动端是如何调试的?
查看>>
常用正则表达式!
查看>>
用JAVA生成老电影海报
查看>>
数组溢界地址的正确使用: 即 int a[6] 中的 a[-1] 和 a[6] 正确使用
查看>>
怎样退出App之前唤醒还有一个App?
查看>>
-bash:jps:command not found
查看>>
cogs 998. [東方S2] 帕秋莉·诺蕾姬
查看>>
BZOJ 1019: [SHOI2008]汉诺塔
查看>>
jquery ocupload一键上传文件应用
查看>>
Java并发编程-看懂AQS的前世今生
查看>>
洛谷 [P3480] KAM-Pebbles
查看>>
操作系统任务调度问题
查看>>
day02-python 基础02
查看>>
.net下Ueditor配置(主要讲解上传功能配置)
查看>>
std::string的Copy-on-Write:不如想象中美好
查看>>
KONG -- 配置 service 并添加 key-auth
查看>>
多重继承和有内嵌对象时构造函数调用顺序
查看>>
C#编码规范
查看>>
信号、槽位及布局
查看>>