HDU
来源:互联网 发布:python 图像分割提取 编辑:程序博客网 时间:2024/05/16 01:46
有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n行第列的格子有几种方案,答案对1000000007取模。
两个整数
Sample Input
4 5
10
没推出公式,看题解都说是杨辉三角:求C(n-2+m-2,m-2),
从一个点可以往右下走,从起点(1,1)到终点(n,m)的方案数,可以分解为需要经过几个中间点的问题,由于可到达的中间点为矩阵(2,2)~(n-1,m-1)内的点,可取的中间点个数为0,1,……min(n-2,m-2),那么找i个中间点其实就是找i个行i个列,其方案数分别为C(m-2,i)*C(n-2,i), i=0到n-2∑C(i,m-2)*C(i,n-2))=C(n-2,m+n-4).
那么组合数求余用Lucas定理,由于求组合数是涉及除法求余,还要用到除法求逆元,即用到公式b^(p-2)==(1/b) (mod p)
代码:
#include<iostream>#include<string>#include<cstdio>#include<algorithm>#include<cmath>#include<iomanip>#include<queue>#include<cstring>#include<map>using namespace std;typedef long long ll;#define M 15#define mod 1000000007ll pow_mod(ll n,ll k){ ll res=1; while(k>0) { if(k&1) res=res*n%mod; n=n*n%mod; k>>=1; } return res;}ll C(ll n,ll m){ if(n<m) return 0; ll ans=1; for(ll i=1;i<=m;i++) { ll a=n-m+i; ll b=i; //本来有ans=ans*(a/b),但是除法不满足取余,利用b^(p-2)==(1/b) (mod p) ans=ans*(a*pow_mod(b,mod-2)%mod)%mod; } return ans;}ll Lucas(ll n,ll m){ if(m==0) return 1; return C(n%mod,m%mod)*Lucas(n/mod,m/mod)%mod;}int main(){ ll n,m; while(scanf("%lld%lld",&n,&m)!=EOF) { ll a=m+n-4; ll b=min(m-2,n-2); printf("%lld\n",Lucas(a,b)); } return 0;}
推理参考:http://blog.csdn.net/queuelovestack/article/details/51476288,
https://www.zybang.com/question/c01c6717d750636e7499faff8288ec36.html
除法求逆元(扩展欧几里德和费马小定理)
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- git添加/删除远程仓库
- 51nod 1065 最小正子段和 -暴力
- Wannafly挑战赛5 A.珂朵莉与宇宙
- c++学习笔记第二篇 筋の給话
- 简述容器之rb_tree及其应用--(boolan)
- HDU
- UVALive 7962|Gym 101201K|Tournament Wins|概率期望|组合数求对数
- 哪家手机车牌识别软件好
- 旧美后感
- 周计划 补完工程 第十四周 R 语言ggplot2(1)
- 操作系统知识点
- 一些重要的算法
- 剑指offer 删除链表中重复的结点
- 机器学习实战-python3决策树实例