D - いろはちゃんとマス目 / Iroha and a Grid
Time Limit: 2 sec / Memory Limit: 256 MB
Score : 400400 points
Problem Statement
We have a large square grid with HH rows and WW columns. Iroha is now standing in the top-left cell. She will repeat going right or down to the adjacent cell, until she reaches the bottom-right cell.
However, she cannot enter the cells in the intersection of the bottom AA rows and the leftmost BB columns. (That is, there are A×BA×B forbidden cells.) There is no restriction on entering the other cells.
Find the number of ways she can travel to the bottom-right cell.
Since this number can be extremely large, print the number modulo 109+7109+7.
Constraints
- 1≦H,W≦100,0001≦H,W≦100,000
- 1≦A<H1≦A<H
- 1≦B<W1≦B<W
Input
The input is given from Standard Input in the following format:
HH WW AA BB
Output
Print the number of ways she can travel to the bottom-right cell, modulo 109+7109+7.
Sample Input 1 Copy
Copy
2 3 1 1
Sample Output 1 Copy
Copy
2
We have a 2×32×3 grid, but entering the bottom-left cell is forbidden. The number of ways to travel is two: "Right, Right, Down" and "Right, Down, Right".
Sample Input 2 Copy
Copy
10 7 3 4
Sample Output 2 Copy
Copy
3570
There are 1212 forbidden cells.
Sample Input 3 Copy
Copy
100000 100000 99999 99999
Sample Output 3 Copy
Copy
1
Sample Input 4 Copy
Copy
100000 100000 44444 55555
Sample Output 4 Copy
Copy
738162020
题意:
给定H,W,A,B,其中H,W分别表示矩形的长宽,A,B表示左下角矩形不能通过,求从(1,1)到(H,W)的方案数,答案对1e9+7取模。
分析:
我们知道不带不可以走的左下角矩形的方案总数:C(H+W-2,H-1)。
错误的情况:(1,1)->I:C(H-A+i-2,H-A-1)
I->(H,W): C(A-1+W-i,A-1)
乘法原理:C(H-A+i-2,H-A-1)* C(A-1+W-i,A-1)
注意这里需要逆元:
C(n,m)=n!/m!*(n-m)!=n!*inv(m)*inv(n-m)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7; // 必须为质数才管用
const ll MAXN = 2e5 + 3;
ll fac[MAXN]; // 阶乘
ll inv[MAXN]; // 阶乘的逆元
ll QPow(ll x, ll n)
{
ll ret = 1;
ll tmp = x % MOD;
while (n)
{
if (n & 1)
{
ret = (ret * tmp) % MOD;
}
tmp = tmp * tmp % MOD;
n >>= 1;
}
return ret;
}
void Init()
{
fac[0] = 1;
for (int i = 1; i < MAXN; i++)
{
fac[i] = fac[i - 1] * i % MOD;
}
inv[MAXN - 1] = QPow(fac[MAXN - 1], MOD - 2);
for (int i = MAXN - 2; i >= 0; i--)
{
inv[i] = inv[i + 1] * (i + 1) % MOD;
}
}
ll C(int a,int b) {
if(a<0||b<0)return 1;
return fac[a]*inv[b]%MOD*inv[a-b]%MOD;
}
int main() {
int H,W,A,B;
int N;
scanf("%d%d%d%d",&H,&W,&A,&B);
N=H+W-2;
Init();
ll ans=C(H+W-2,H-1);
for(ll i=1;i<=B;i++) {
ans-=C(H-A+i-2,H-A-1)*C(A-1+W-i,A-1)%MOD;
ans=(ans%MOD+MOD)%MOD;
}
printf("%lld",ans);
return 0;
}