思路:f(i,j)表示机器人从左上角到(i,j)的方法数,则f(i,j)=f(i-1,j)+f(i,j-1),这是因为机器人只能走下或走右。模拟一遍可得f(i,j)=C(i+j-2,m-1),由于i,j比较大,所以利用卢卡斯大组合数取膜。
1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <algorithm> 10 #include <cmath> 11 #include <cstring> 12 #include <cstdlib> 13 #include <string> 14 #include <sstream> 15 #include <time.h> 16 #define x first 17 #define y second 18 #define pb push_back 19 #define mp make_pair 20 #define lson l,m,rt*2 21 #define rson m+1,r,rt*2+1 22 #define mt(A,B) memset(A,B,sizeof(A)) 23 #define mod 1000000007 24 using namespace std; 25 typedef long long LL; 26 const double PI = acos(-1); 27 const int N=1e5+10; 28 const int inf = 0x3f3f3f3f; 29 const LL INF=0x3f3f3f3f3f3f3f3fLL; 30 LL exp_mod(LL a, LL b, LL p) 31 { 32 LL res = 1; 33 while(b != 0) 34 { 35 if(b&1) res = (res * a) % p; 36 a = (a*a) % p; 37 b >>= 1; 38 } 39 return res; 40 } 41 LL Comb(LL a, LL b, LL p) 42 { 43 if(a < b) return 0; 44 if(a == b) return 1; 45 if(b > a - b) b = a - b; 46 LL ans = 1, ca = 1, cb = 1; 47 for(LL i = 0; i < b; ++i) 48 { 49 ca = (ca * (a - i))%p; 50 cb = (cb * (b - i))%p; 51 } 52 ans = (ca*exp_mod(cb, p - 2, p)) % p; 53 return ans; 54 } 55 LL Lucas(int n, int m, int p) 56 { 57 LL ans = 1; 58 while(n&&m&&ans) 59 { 60 ans = (ans*Comb(n%p, m%p, p)) % p; 61 n /= p; 62 m /= p; 63 } 64 return ans; 65 } 66 int main() 67 { 68 #ifdef Local 69 freopen("data.txt","r",stdin); 70 #endif 71 int m,n; 72 cin>>n>>m; 73 cout<<Lucas(n+m-2,m-1,mod)<<endl; 74 #ifdef Local 75 cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl; 76 #endif 77 }