题意:n*m的格子,中间有若干点不能走,问从左上角到右下角有多少种走法。
思路:CountWay(i,j) 表示从 i 点到 j 点的种数。然后用容斥原理加加减减解决
1 #pragma comment(linker, "/STACK:1000000000") 2 #include <iostream> 3 #include <cstdio> 4 #include <fstream> 5 #include <algorithm> 6 #include <cmath> 7 #include <deque> 8 #include <vector> 9 #include <queue> 10 #include <string> 11 #include <cstring> 12 #include <map> 13 #include <stack> 14 #include <set> 15 #define LL long long 16 #define MAXN 100005 17 #define MOD 1000000007 18 #define INF 0x3f3f3f3f 19 #define eps 1e-8 20 using namespace std; 21 struct Node 22 { 23 LL x, y; 24 }; 25 Node p[MAXN]; 26 LL factor[2 * MAXN], w[2 * MAXN]; 27 LL res[MAXN]; 28 bool compare(Node a, Node b) 29 { 30 return a.x < b.x || (a.x == b.x && a.y < b.y); 31 } 32 LL CountWay(LL x, LL y) 33 { 34 LL res = factor[x + y]; 35 res = res * w[x] % MOD; 36 res = res * w[y] % MOD; 37 return res; 38 } 39 LL quick_power(LL x, LL y) 40 { 41 if (y == 0){ 42 return (LL)1; 43 } 44 if (y == 1){ 45 return x % MOD; 46 } 47 LL res = quick_power(x, y >> 1); 48 res = (res * res) % MOD; 49 if (y & 1){ 50 res = (res * x) % MOD; 51 } 52 return res; 53 } 54 int main() 55 { 56 #ifndef ONLINE_JUDGE 57 freopen("in.txt", "r", stdin); 58 //freopen("out.txt", "w", stdout); 59 #endif // OPEN_FILE 60 int T; 61 factor[0] = 1; 62 w[0] = 1; 63 for (LL i = 1; i <= 200000; i++){ 64 factor[i] = (factor[i - 1] * i) % MOD; 65 w[i] = quick_power(factor[i], MOD - 2); 66 } 67 scanf("%d", &T); 68 LL n, m, k; 69 while (T--){ 70 scanf("%I64d%I64d%I64d", &n, &m, &k); 71 for (int i = 1; i <= k; i++){ 72 scanf("%I64d%I64d", &p[i].x, &p[i].y); 73 } 74 p[k + 1].x = n; 75 p[k + 1].y = m; 76 sort(p + 1, p + k + 1, compare); 77 for (int i = 1; i <= k + 1; i++){ 78 res[i] = CountWay(p[i].x - 1, p[i].y - 1); 79 } 80 for (int i = 1; i <= k + 1; i++){ 81 for (int j = i + 1; j <= k + 1; j++){ 82 if (p[j].x < p[i].x || p[j].y < p[i].y) continue; 83 //if(p[j].x == p[i].x && p[j].y == p[i].y) continue; 84 res[j] = (res[j] - (res[i] * CountWay(p[j].x - p[i].x, p[j].y - p[i].y)) % MOD) % MOD; 85 } 86 } 87 printf("%I64d\n", (res[k + 1] + MOD) % MOD); 88 } 89 }