hdu 5673 robot【默慈金数or卡特兰数】
2016-04-26 20:33
288 查看
补充知识:
卡特兰数
Catalan(n)=Cn2nn+1
Catalan(n)=4n−2n+1∗Catalan(n−1)
默慈金数
Mn=∑n/2i=0C2in∗Catalan(i)
Mn+1=Mn+∑n−1i=0MiMn−1−i=(2n+3)Mn+3nMn−1n+3
线性求解1~p-1mod p的逆元
inv[i] = (p - p / i) * inv[p%i] % p。
详情参考:
默慈金数 http://blog.csdn.net/acdreamers/article/details/41213667
线性求逆元 http://blog.miskcoo.com/2014/09/linear-find-all-invert
题目大意:
机器人只能在原点及原点右侧,符合规定下可以选择左移一个、右移一个或原地不动,起点在原点,问有几种方式使机器人n次操作后回到原点,结果对1e9+7取余。
思路:
机器人最多走到n/2处;
在0-n/2中的i处,走到i在回到原点的方式有C2in∗Catalan(i)种;
因此ans(n)=∑n/2i=0C2in∗Catalan(i)。
也可以直接套默慈金数递推公式。
1.默慈金数代码
2.catalan数
卡特兰数
Catalan(n)=Cn2nn+1
Catalan(n)=4n−2n+1∗Catalan(n−1)
默慈金数
Mn=∑n/2i=0C2in∗Catalan(i)
Mn+1=Mn+∑n−1i=0MiMn−1−i=(2n+3)Mn+3nMn−1n+3
线性求解1~p-1mod p的逆元
inv[i] = (p - p / i) * inv[p%i] % p。
详情参考:
默慈金数 http://blog.csdn.net/acdreamers/article/details/41213667
线性求逆元 http://blog.miskcoo.com/2014/09/linear-find-all-invert
题目大意:
机器人只能在原点及原点右侧,符合规定下可以选择左移一个、右移一个或原地不动,起点在原点,问有几种方式使机器人n次操作后回到原点,结果对1e9+7取余。
思路:
机器人最多走到n/2处;
在0-n/2中的i处,走到i在回到原点的方式有C2in∗Catalan(i)种;
因此ans(n)=∑n/2i=0C2in∗Catalan(i)。
也可以直接套默慈金数递推公式。
1.默慈金数代码
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const LL mod = 1e9 + 7; const LL MAXN = 1e6 + 100; LL inv[MAXN], m[MAXN]; int main(int argc, char const *argv[]) { inv[1] = 1; for(int i = 2; i < MAXN; i++) inv[i] = (mod - mod / i) * inv[mod % i] % mod; //预处理逆元 m[1] = 1; m[2] = 2; for(int i = 3; i < MAXN; i++) //默慈金数打表 { m[i] = (2 * i + 1) * m[i-1] % mod + 3 * (i - 1) * m[i-2] % mod; m[i] = m[i] % mod * inv[i+2] % mod; } int t; scanf("%d", &t); while(t--) { int n; scanf("%d", &n); printf("%I64d\n", m ); } return 0; }
2.catalan数
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const LL mod = 1e9 + 7; const LL MAXN = 1e6 + 100; LL inv[MAXN], c[MAXN], cat[MAXN]; int main(int argc, char const *argv[]) { inv[1] = 1; for(int i = 2; i < MAXN; i++) inv[i] = (mod - mod / i) * inv[mod % i] % mod; cat[0] = 1; cat[1] = 1; for(int i = 2; i < MAXN; i++) //预处理卡特兰数 { cat[i] = (4 * i - 2) * cat[i-1] % mod; cat[i] = cat[i] * inv[i+1] % mod; } int t; scanf("%d", &t); while(t--) { int n; scanf("%d", &n); c[0] = 1; for(int i = 1; i <= n; i++) //c(n i)组合数 { c[i] = (n - i + 1) * c[i-1] % mod; c[i] = c[i] * inv[i] % mod; } LL ans = 0; for(int i = 0; i <= n/2; i++) { ans += c[i<<1] * cat[i] % mod; ans %= mod; } printf("%I64d\n", ans); } return 0; }
相关文章推荐
- 出栈顺序与Catalan数
- 【ACM Steps】2.2.6 HDOJ 1023 Train Problem II JAVA解决卡特兰大数问题
- 卡特兰数及括号正确匹配个数问题解释
- 卡特兰数(HDU 1023)
- 1139: 出栈序列统计
- 打印括号匹配的所有排列
- 卡特兰数
- 关于栈的出栈顺序的研究
- 卡特兰数的研究
- 卡特兰数
- catalan数
- hdu2067 组合数学 卡特兰数
- 工具之卡特兰数(1~100)
- ACM-卡特兰数之Train Problem II——hdu1023
- HDU 5673 Robot(卡特兰数)
- 卡特兰数的两种计算方法
- HDU1023(JAVA···高精度卡特兰数)
- Count the Trees-卡特兰数\高精度乘法
- 卡特兰数
- Catalan数(高精版)