HDU 5673 Robot 卡特兰数

  题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5673

  题目描述: 一个人从原点开始向右走, 要求N秒后回到原点, 且过程中不能到负半轴, 人有两种操作, 走动或者停止, 问总共有多少种方案?

  解题思路: 类似于括号匹配问题, 和那个我去年这个时候接触到的最裸的不能越过对角线的正方形走到对角问题, 卡特兰数, 从2开始枚举走动步数, 然后剩下的就是不动的步数, 用不动的步数做个填充就可以了, 设计到取模, 需要逆元

  代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iterator>
#include <cmath>
#include <algorithm>
#include <stack>
#include <deque>
#include <map>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,-0x3f,sizeof(a))
#define fi(n) for(i=0;i<n;i++)
#define fj(m) for(j=0;j<m;j++)
#define sca(x) scanf("%d",&x)
#define ssca(x) scanf("%s",x)
#define scalld(x) scanf("%I64d",&x)
#define print(x) printf("%d\n", x)
#define printlld(x) printf("%I64d\n",x)
#define de printf("=======\n")
#define yes printf("YES\n")
#define no printf("NO\n")
typedef long long ll;
using namespace std;

const int mod = 1e9+7;
const int maxn = 1e6+100;

ll inv[maxn];
ll h[maxn];
ll c[maxn];

void init() {
    inv[1] = 1;
    for( int i = 2; i < maxn; i++ ) { // 预处理逆元
        inv[i] = (mod - mod / i) * inv[mod%i] % mod;
    }
}

int main() {
    init();
    int t;
    int n;
    h[0] = h[1] = 1;
    for( int i = 2; i < maxn; i++ ) { // 卡特兰数
        h[i] = h[i-1] * (4*i-2)%mod * inv[i+1] % mod;
    }
    sca(t);
    while( t-- ) {
        sca(n);
        ll ans = 1;
        c[0] = 1;
        for( int i = 1; i <= n; i++ ) { // 组合数
            c[i] = c[i-1] * (n-i+1) % mod * inv[i] % mod;
        }
        for( int i = 1; ; i++ ) {
            int k = n - (i<<1);
            if( k < 0 ) break;
            ans = (ans + h[i] * c[k]) % mod;
        }
        printf( "%lld\n", ans );
    }
    return 0;
}

  思考: 很裸的卡特兰数, 组合数学很有意思, 然后就是说我感觉现在需要开始整理一下板子了, 比如说这个, 还有那个神题等等, 洗完澡回来再说, 我好菜啊

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

时间: 2024-08-03 07:08:11

HDU 5673 Robot 卡特兰数的相关文章

hdu 5673 Robot 卡特兰数+逆元

Robot Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description There is a robot on the origin point of an axis.Every second, the robot can move right one unit length or do nothing.If the robot is on the

HDU 5673 Robot(卡特兰数)

题目链接:点击打开链接 思路:卡特兰数可以用来求括号序列的个数, 用了组合数学的知识. 该题其实就等价于求一个括号序列的个数, 因为满足任意时刻, 向右的步数大于等于向左的步数. 但是该题还有停止不动的情况, 所以我们不妨枚举向右的步数, 然后求出括号序列的组合数, 然后剩下的就是停止不动的步数, 用组合数插空即可. 另外, 除法取模要取逆元, 我们可以线性预处理出所有逆元. 细节参见代码: #include<cstdio> #include<cstring> #include&l

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

Robot Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 483    Accepted Submission(s): 244 Problem Description There is a robot on the origin point of an axis.Every second, the robot can move rig

hdu5673 Robot 卡特兰数 / 默慈金数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5673 分析: 这道题是一道裸的默慈金数,比较容易想到的是用卡特兰数来做.不了解的可以先学习一下. 卡特兰数:http://www.cnblogs.com/yaoyueduzhen/p/5456490.html 默慈金数:http://www.cnblogs.com/yaoyueduzhen/p/5456530.html 记路径长度为nn,那么机器人最多向右走⌊?n/2??⌋步并向左走⌊?n/2??⌋

hdu 5184 类卡特兰数+逆元

BC # 32 1003 题意:定义了括号的合法排列方式,给出一个排列的前一段,问能组成多少种合法的排列. 这道题和鹏神研究卡特兰数的推导和在这题中的结论式的推导: 首先就是如何理解从题意演变到卡特兰数: 排列的总长度为 n ,左右括号各为 m = n / 2 个.当给定的排列方式完全合法的时候,剩下需要排列的左右括号的数量就已经确定了,而在排列的过程中,左括号要始终大于等于右括号的数量.设现在有 a 个左括号, b 个右括号,那么这个就可以当做从( a , b )点到 ( m , m )点且不

组合数学--卡特兰数-持续更新

参考资料: 基本介绍和各种分类 http://www.cnblogs.com/topW2W/p/5410875.html 另类递归式: h(n)=h(n-1)*(4*n-2)/(n+1);  (从n开始,更常用) 前几个卡特兰数:规定C0=1,而 分类 :  括号,栈,矩阵乘法,     凸多边形划分,二叉搜索树构造      步数上下,找零, C1=1,C2=2,C3=5,C4=14,C5=42, C6=132,C7=429,C8=1430,C9=4862,C10=16796, C11=587

hdu 5177 (1e18范围的卡特兰数)

hdu 5177 (1e18范围的卡特兰数) 题意: 求第n个卡特兰数,模3814697265625 (5^18) 限制: 有20组数据,1 <= n <= 1e18 思路: 1. 卡特兰数的表达式: ans = 1/(n+1) * C(2*n,n) -> ans = 1/(n+1) * (2n)! / n! / n!    ---1式 2. 因为要模5^18,求逆元要求互质,所以先把"1式"中的因子5全部去掉 3. 然后看不含因子5的阶乘,f(n!) 4. 设g(x

hdu 4828 Grids(拓展欧几里得+卡特兰数)

题目链接:hdu 4828 Grids 题目大意:略. 解题思路:将上一行看成是入栈,下一行看成是出栈,那么执着的方案就是卡特兰数,用递推的方式求解. #include <cstdio> #include <cstring> typedef long long ll; const int N = 1000005; const ll MOD = 1e9+7; ll dp[N]; ll extendGcd(ll a, ll b, ll& x, ll& y) { if (

2014年百度之星程序设计大赛 - 初赛(第一轮) hdu Grids (卡特兰数 大数除法取余 扩展gcd)

题目链接 分析:打表以后就能发现时卡特兰数, 但是有除法取余. f[i] = f[i-1]*(4*i - 2)/(i+1); 看了一下网上的题解,照着题解写了下面的代码,不过还是不明白,为什么用扩展gcd, 不是用逆元吗.. 网上还有别人的解释,没看懂,贴一下: (a / b) % m = ( a % (m*b)) / b 笔者注:鉴于ACM题目特别喜欢M=1000000007,为质数: 当gcd(b,m) = 1, 有性质: (a/b)%m = (a*b^-1)%m, 其中b^-1是b模m的逆