Problem

有一个\(1*n\)的矩阵,固定第一个数为\(1\),其他填正整数, 且相邻数的差不能超过\(1\),求方案数。

\(n\le 10^6\)

Solution

容易发现答案是\(f_n=f_{n-1}*3-g_{n}\)。

其中\(g_i\)表示从\((0,0)\)走到\((i,0)\)可以向上,向下向右走一格,但是只能在第一象限的方案数。

然后这个显然可以用 组合数 + 卡特兰数 推一波:$$\sum_{i=1}^{\frac{n}{2}}\binom{n}{2i}Catalan_{i}$$但时间复杂度是\(O(n^2)\)的。

然后去学了一发姿势,发现这个是所谓的默慈金数

一个给定的数\(n\)的默慈金数是:

  • 在一个圆上的\(n\)个点间,画出彼此不相交的弦的方案数

其中,\(M(1)=1,M(2)=2\)

\[M(n+1)=M(n)+\sum_{i=0}^{n-1}M(i)*M(n-1-i)
\]

可以推导出$$M(n+1)={{(2n+3)M(n)+3nM(n-1)}\over n+3}$$

\[M(n)={{(2n+1)M(n-1)+(3n-3)M(n-2)}\over n+2}
\]

有较好英文水平姿势的同学可以参考推导极其生成函数(反正我是不可能会的),考场上我觉得只要会\(O(n^2)\)的方法,然后只需知道它是由\(n-1,n-2\)推到\(n\),找一下规律应该可以。。。

http://mathworld.wolfram.com/MotzkinNumber.html

http://www.docin.com/p1-964777006.html

Code
#include <bits/stdc++.h>

#define F(i,a,b) for (int i = a; i <= b; i ++)

using namespace std;

const int N = 1e6 + 10;
const int Mo = 1e9 + 7; long long f[N], M[N], n; int ksm(int x, int y) {
int ans = 1;
for (; y ; y >>= 1, x = (1ll * x * x) % Mo)
if (y & 1)
ans = (1ll * ans * x) % Mo;
return ans;
} int main() {
scanf("%d", &n); f[1] = 1, f[2] = 2;
M[1] = 1, M[2] = 2;
F(i, 3, n) {
M[i] = ((2 * i + 1) * M[i - 1] + (3 * i - 3) * M[i - 2]) % Mo * ksm(i + 2, Mo - 2) % Mo;
f[i] = (f[i - 1] * 3 - M[i - 2]) % Mo;
} printf("%d\n", (f[n] + Mo) % Mo);
}

51nod1556 计算(默慈金数)的更多相关文章

  1. 51 Nod 1556计算(默慈金数的应用)

    #include<bits/stdc++.h> #define mod 1000000007 using namespace std; typedef long long ll; ll m ...

  2. hdu5673 Robot 卡特兰数 / 默慈金数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5673 分析: 这道题是一道裸的默慈金数,比较容易想到的是用卡特兰数来做.不了解的可以先学习一下. 卡特 ...

  3. HDU5673 Robot 默慈金数

    分析: 注:然后学了一发线性筛逆元的姿势 链接:http://blog.miskcoo.com/2014/09/linear-find-all-invert #include<iostream& ...

  4. hdu-5673 Robot(默次金数)

    题目链接: Robot Time Limit: 12000/6000 MS (Java/Others)  Memory Limit: 65536/65536 K (Java/Others) 问题描述 ...

  5. 51nod1556 计算

    ans[n]=ans[n-1]*3-m[n-2];YY一下可以懂的.减掉的就是往下走的情况不符合正整数的情况.m是默慈金数. #include<cstdio> #include<cs ...

  6. Python 素数判断;以及默尼森数

    1. 素数/质数 只能被2或者本身整除的正整数. 2. 默尼森数 P是素数且M也是素数,并且满足等式M=2^P-1,则称M为默尼森数. 编程小要求: 输出前5个默尼森数 1)最外层循环找素数 中间层循 ...

  7. python计算文件的行数和读取某一行内容的实现方法

    一.计算文件的行数 最简单的办法是把文件读入一个大的列表中,然后统计列表的长度.如果文件的路径是以参数的形式filepath传递的,那么只用一行代码就可以完成我们的需求了:count = len(op ...

  8. js计算字符串的字节数和字符串与二进制的相互转化

    一.js计算字符串的字节数方法: //blob获取字符串的字节 var debug = "好的"; var blob = new Blob([debug],{type : 'tex ...

  9. 【转载】python计算文件的行数和读取某一行内容的实现方法

    一.计算文件的行数 最简单的办法是把文件读入一个大的列表中,然后统计列表的长度.如果文件的路径是以参数的形式filepath传递的,那么只用一行代码就可以完成我们的需求了: count = len(o ...

随机推荐

  1. java反序列化漏洞实战

    准备: 域名一个,用于增加NS解析,判断是否存在反序列化漏洞. 公网IP服务器一台,用于搭建DNS代理,抓包判断. dnschef,DNS代理 ysoserial.jar生成payload. 简单的p ...

  2. 《JavaScript高级程序设计》笔记:面向对象的程序设计(六)

    面向对象的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象. 理解对象 创建自定义对象的最简单的方法就是创建一个Object的实例,然后再为它添加属性和方法.例 ...

  3. Odoo 开源微信小程序商城模块

    详见:http://oejia.net/blog/2018/09/13/oejia_weshop_about.html oejia_weshop Odoo 微信小程序商城模块 oejia_weshop ...

  4. 生鲜配送管理系统_升鲜宝 V2.0 小程序辅助系统工具矩阵系列相关说明

    随着微信红利的进一步释放,使用人群的不断增加,小程序从2017年01月第一批开发者出现后,2018年小程序得到快速的提升,小程序开发的相关应用小工具得到了市场的青咪,社会化大分工.协同.共享.协作的思 ...

  5. 我的Windows日常——Win7完美兼容tsmmc.msc的方法

    操作步骤 32位操作系统: 1.将2003系统C:\WINDOWS\system32目录下的mstsmhst.dll.mstsmmc.dll.tsmmc.msc拷贝到Windows7系统中的C:\WI ...

  6. windows 2008 开机启动 Docker Toolbox 并运行容器

    新建 docker-startup.bat @echo off REM Set the name of the VM configuration where dockerd will be hoste ...

  7. Storm入门(一)原理介绍

    问题导读:1.hadoop有master与slave,Storm与之对应的节点是什么?2.Storm控制节点上面运行一个后台程序被称之为什么?3.Supervisor的作用是什么?4.Topology ...

  8. springboot 定时任务

    1.启动类新增注解 @EnableScheduling import org.springframework.boot.SpringApplication; import org.springfram ...

  9. 如何在FineUIMvc(ASP.NET MVC)中显示复杂的表格列数据(列表和对象)?

    起源 最初,这个问题是知识星球内的一个网友提出的,如何在FineUIMvc中展现复杂的列数据? 在FineUIPro中,我们都知道有一个 TemplateField 模板列可以使用,我们只需要在后台定 ...

  10. mysql查询order by 指定字段排序

    当MySQL查询时排序的字段不是数字时而是汉字的时候也可以用when  then 来指定排序. 列如yewu_check表的status 字段不是0,1,2而是汉字待办,已办,退回.可以如下写法: S ...