加油 ( •̀ ω •́ )y!

1119 机器人走方格 V2 (组合数学)

M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。
 
Input
第1行,2个数M,N,中间用空格隔开。(2 <= m,n <= 1000000)
Output
输出走法的数量 Mod 10^9 + 7。
Input示例
2 3
Output示例
3
思路: 我们从左上走到右下 一共要往下走n-1次 往右走 m-1次 一共走了 n+m-2次但是不同的地方可以在向下走(n-1)次 或者向右走(m-1)次 所以我们在这里有C(n+m-2,n-1)或者
C(n+m-2,m-1)种走法 这两种是相同的。而我们在运算时 对组合数取余 由于组合数存在除法, 而取余不能再商之后取余,所以这里我们需要将除法转换成乘法来做。
 (( A!)/(B!)) % P等价于(A! * (B!)^-1)%P 而 B!^-1 成为B!的逆元由费马小定理可知 B!^-1 = B^(P-2)  然后B^P-2 可以由快速幂来求 
  PS:这里的P要求为质数
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 typedef long long LL;
 6 const LL mod = 1e9+7;
 7 LL m,n;
 8 LL Pow(LL a,LL b)//快速幂  a的b次方 
 9 {
10     LL ans=1;
11     while(b)
12     {
13         if(b&1)
14             ans=ans*a%mod;
15         b>>=1;
16         a=a*a%mod;
17     }
18     return ans;
19 }
20 LL index(int x) //求阶乘取余  
21 {
22     LL ans = 1;
23     for(int i=1;i<=x;i++)
24         ans = ans*i%mod;
25     return ans;
26 }
27 LL C(int a,int b)//组合数 
28 {
29     LL ans = 1;
30     ans = ans%mod * index(a)%mod;
31     ans = ans%mod * Pow(index(a-b),mod-2)%mod;
32     ans = ans%mod * Pow(index(b),mod-2)%mod;
33     
34     return ans%mod;
35 }
36 int main()
37 {
38     cin>>m>>n;
39     cout<<C(n+m-2,n-1)<<endl;
40     return 0;
41 }

 

posted @ 2018-03-17 14:18  皮皮虎  阅读(226)  评论(0编辑  收藏  举报