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. typescript类的修饰符

    学习过java的小姐姐,小哥哥应该很好理解,但还是啰嗦的写出来! typescript里面定义属性的时候给我们提供了 三种修饰符 public :公有 在当前类里面. 子类 .类外面都可以访问 pro ...

  2. java class反编译工具----JD-GUI

    下载地址   http://jd.benow.ca/

  3. 'Attempt to create two animations for cell' iOS

    我是在对一个UITableView 一起进行 reloadRows和reloadSections 的操作的时候 出现的

  4. csrf漏洞实战演练

    定义: 修改密码操作:

  5. Centos7上安装单机版redis

    Centos 7 上安装单机版redis Redis 官网下载 https://redis.io/download 1. 下载.解压.安装 cd /usr/local #wget http://dow ...

  6. django项目外部的脚本文件执行ORM操作,无需配置路由、视图启动django服务

    #一.将脚本路径添加到python的sys系统环境变量里 import sys # sys.path.append('c:/Users/Administrator/www/mymac') #第一种.绝 ...

  7. Photoshop给草坡上的人物加上大气的霞光

    <点小图查看大图> 最终效果 1.打开原图素材大图,创建可选颜色调整图层,对红色.黄色.黑色进行调整,参数设置如图1 - 3,效果如图4.这一步减少图片中的红色,并给暗部增加蓝色. < ...

  8. SSZipArchive的使用详解和遇到的问题

    https://blog.csdn.net/zhengang007/article/details/51019479 2016年03月30日 版权声明:本文为博主原创文章,转载请注明作者和原文链接. ...

  9. ArrayBlockingQueue源码分析

    ArrayBlockingQueue是一个基于数组实现的有界的阻塞队列. 属性 //底层存储元素的数组.为final说明一旦初始化,容量不可变,所以是有界的. final Object[] items ...

  10. 编译安装MySQL5.6失败的相关问题解决方案

    Q0:需要安装git 解决方案: #CentOS yum install git #ubuntu apt-get install git Q1:CMAKE_CXX_COMPILER could be ...