HDU 5698 瞬间移动

瞬间移动

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 192    Accepted Submission(s): 99


Problem Description
有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n行第m的格子有几种方案,答案对1000000007取模。
 
 
 
Input
多组测试数据。

两个整数nm(2 <= n, m <= 100000)
 
 
 
Output
一个整数表示答案
 

 

Sample Input
4 5
 

 

Sample Output
10
 

 

Source
 
 
 
解析:首先可推出公式为C(n+m-4, n-2)对1000000007取模。接下来问题就转化为计算C(n+m-4, n-2) % 1000000007,而C(n+m-4, n-2) = (n+m-4)! / ((n-2)! * (m-2)!) % 1000000007,故需要求 (n-2)! 和 (m-2)! 的逆元。因为MOD = 1000000007为素数,则对应的逆元分别为 (n-2)!MOD-2 % MOD、(m-2)!MOD-2 % MOD。
最终结果为 (n+m-4)! * (n-2)!MOD-2 % MOD * (m-2)!MOD-2 % MOD。
 
 
 
 1 #include <cstdio>
 2 
 3 const int MOD = 1000000007;
 4 int n, m;
 5 long long f[200010];
 6 
 7 //求阶乘
 8 void init()
 9 {
10     f[0] = 1;
11     for(int i = 1; i <= 200000; ++i){
12         f[i] = f[i-1]*i%MOD;
13     }
14 }
15 
16 long long quickpowmod(long long x, long long y)
17 {
18     long long ret = 1;
19     while(y){
20         if(y&1)
21             ret = ret*x%MOD;
22         x = x*x%MOD;
23         y >>= 1;
24     }
25     return ret;
26 }
27 
28 int main()
29 {
30     init();
31     while(~scanf("%d%d", &n, &m)){
32         printf("%I64d\n", f[n+m-4]*quickpowmod(f[n-2], MOD-2)%MOD*quickpowmod(f[m-2], MOD-2)%MOD);
33     }
34     return 0;
35 }

 

1000000007

posted on 2016-05-22 19:49  月夜下  阅读(393)  评论(0编辑  收藏  举报

导航

"320px">