HDU 5673 Robot(默慈金数)

Posted jpphy0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5673 Robot(默慈金数)相关的知识,希望对你有一定的参考价值。

链接

Robot - http://acm.hdu.edu.cn/showproblem.php?pid=5673

分析

  • 从原点出发回到原点,且不会出现在原点左侧

  • 从开始到任意时刻,向右步数不少于向左步数,且最终向右、向左步数相等;

  • 若共 n n n步,向右和向左各 k k k步,则不动有 n − 2 k n-2k n2k步,因此, C n n − 2 k × C k , k ∈ { 0 , 1 , 2 , … , ⌊ n 2 ⌋ } C_n^{n-2k} \\times C_k,k\\in\\{0,1,2,…,\\lfloor\\frac{n}{2}\\rfloor\\} Cnn2k×Ckk{0,1,2,2n}

  • 这是一个 ± 1 、 0 \\pm1、0 ±10 模型,其中 ± 1 \\pm1 ±1 满足卡特兰模型

  • 结论 M n = C n n × C 0 + C n n − 2 × C 1 + … + C n n − 2 × k × C k + … + C n n − 2 × ⌊ n 2 ⌋ × C ⌊ n 2 ⌋ M_n= C_n^n \\times C_0 + C_n^{n-2} \\times C_1 + … + C_n^{n-2 \\times k} \\times C_k+ …+ C_n^{n-2 \\times \\lfloor\\frac{n}{2}\\rfloor} \\times C_{\\lfloor\\frac{n}{2}\\rfloor} Mn=Cnn×C0+Cnn2×C1++Cnn2×k×Ck++Cnn2×2n×C2n

  • C k C_k Ck为卡特兰数, M n M_n Mn称为默慈金数(Motzkin Number)

    • 在一个圆上的n个点间画出彼此不相交的弦的全部方法的总数【允许某些或全部点不连线】

      • 4个点,9种连接方法在这里插入图片描述
      • 5个点,21种连接方法在这里插入图片描述
    • 在一个“网格”上,若限定“每步只能向右移动一格(可以向右上、右下横向向右),并禁止移动到y=0以下的地方”,则以这种走法用n步从(0,0)移动至(n,0)的可能形成的路径的总数为n的默慈金数。
      在这里插入图片描述

    • 最初的几个默慈金数如下(OEIS中的数列A001006):1, 2, 4, 9, 21, 51, 127, 323, 835, 2188, 5798, 15511, 41835, 113634, 310572, 853467, 2356779, 6536382, 18199284, 50852019, 142547559, 400763223, 1129760415, 3192727797, 9043402501, 25669818476, 73007772802, 208023278209, 593742784829

    • 递推式 M n + 1 = M n + ∑ i = 0 n − 1 M i × M n − 1 − i = 2 n + 3 n + 3 M n + 3 n n + 3 M n − 1 M_{n+1}=M_n+\\sum_{i=0}^{n-1}M_i \\times M_{n-1-i}=\\frac{2n+3}{n+3}M_n+\\frac{3n}{n+3}M_{n-1} Mn+1=Mn+i=0n1Mi×Mn1i=n+32n+3Mn+n+33nMn1

  • 此外,本题取模运算涉及费马小定理逆元

代码

默慈金数

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MXN 1000010
#define MOD 1000000007
ll mtz[MXN] =  {0, 1, 2}; // 默慈金数
ll inv(ll base, int power){ // 快速幂求逆元
	ll res = 1;
	while(power){
		if(power & 1) res = res*base%MOD;
		base = base*base%MOD;
		power >>= 1;
	}
	return res;
}
void init(){ // 打表
    for(int i = 2; i < MXN; i++){
        mtz[i+1] = (((2*i+3)*mtz[i] + 3*i*mtz[i-1])%MOD*inv(i+3, MOD-2))%MOD;
	}
}
int main(){
    int T, n;
	init();
	cin >> T;
    while(T--){
        cin >> n;
		cout << mtz[n] << endl;
    }
    return 0;
}

以上是关于HDU 5673 Robot(默慈金数)的主要内容,如果未能解决你的问题,请参考以下文章

Robot(hdu5673)

HDU 5673 Robot 卡特兰数

1556 计算

~小结论~

hdu5673 Robot 卡特兰数+组合数学+线性筛逆元

HDU 5007 Post Robot