瞬间移动Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n 行第m 列的格子有几种方案,答案对1000000007 取模。
Input 多组测试数据。
Output 一个整数表示答案
Sample Input 4 5
Sample Output 10
Source 2016"百度之星" - 初赛(Astar Round2B)
Recommend wange2014 确实这个规律,想不到啊 杨辉三角打表 我们发现规律就是求组合数C(n+m-4,m-2) |
代码实现:
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
typedef long long LL;
const LL p=1e9+7;
//适用于p很大
LL quick_mod(LL a, LL b) //快速幂
{
LL ans = 1;
a %= p;
while(b)
{
if(b & 1)
{
ans = ans * a % p;
b--;
}
b >>= 1;
a = a * a % p;
}
return ans;
}
LL C(LL n, LL m) //求组合C(n,m)
{
if(m > n) return 0; //n<m, c(n,m)=0
LL ans = 1;
for(int i=1; i<=m; i++)
{
LL a = (n + i - m) % p;
LL b = i % p;
ans = ans * (a * quick_mod(b, p-2) % p) % p;
}
return ans;
}
LL Lucas(LL n, LL m) //lucass定理
{
if(m == 0) return 1;
return C(n % p, m % p) * Lucas(n / p, m / p) % p;
}
int main()
{
LL n,m;
while(scanf("%I64d%I64d", &n, &m)!=EOF)
{
printf("%I64d\n", Lucas(m+n-4,m-2));
}
return 0;
}