(排列组合)计蒜客——蒜头君走迷宫

蒜头君从一个 n 行 m 列的迷宫的左上角走到右下角,蒜头君每次只能向下或者向右走一步,蒜头君想知道他有多少种走法。

输入格式

输入两个个整数 n(2 \le n \le 10^5),m(2 \le m \le 10^5)。  

输出格式

由于方案数太多,输出最后结果对 1000000007取模的结果。

样例输入1

2 3

样例输出1

3

样例输入2

5 4

样例输出2

35

提示:用 inv[i]=(p−p/i)inv[p%i]%p 这个公式来线性预处理逆元。

#include
#include
using namespace std;

typedef long long LL;

const LL mod = 1000000007;

int m, n;

/*
n行m列的迷宫,从左上角走到右下角,总共需走n+m-2步,其中n-1步是向下走的,m-1步是向右走的
那可能的走法就有C(n+m-2, n-1)种
表示成阶层运算就是 (n+m-2)!
				  ----------
				  (m-1)!(n-1)!
*/

LL Rank[200001];   //rank[i]表示i的阶层
LL inv[100001];    //inv[i]表示i的逆元
LL invRank[100001];    //invRank[i]表示i的阶层的逆元

void init(){
	//初始化Rank
	Rank[0] = Rank[1] = 1;
	for (int i = 2; i < 200000; i++) {
		Rank[i] = (Rank[i - 1] * i) % mod;
	}
	
	//初始化inv&invRank
	inv[1] = 1;
	for (int i = 2; i < 100000; i++) {
		inv[i] = (mod - mod / i)*inv[mod%i] % mod;
	}
	invRank[0] = invRank[1] = 1;
	for (int i = 2; i < 100000; i++) {
		invRank[i] = (invRank[i - 1] * inv[i]) % mod;
	}
}

int main() {	
	init();

	cin >> n >> m;

	cout << Rank[n + m - 2] * invRank[n - 1]%mod * invRank[m - 1]%mod << endl;

	return 0;
}

 

你可能感兴趣的:(算法)