AtCoder Regular Contest 058 (组合数学,D - いろはちゃんとマス目 / Iroha and a Grid)

题目链接:

https://atcoder.jp/contests/arc058/tasks/arc058_b

题目描述:

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

 

题意:

          给定一个N*M的矩阵,问从左上角到右下角有多少种走法,其中左下角的一块kK*L的矩形不能被经过。

思路:

          首先我们知道,如果没有左下角的限制。那么从左上角到右下角的方案书==C(n+m-2,n-1)。

加上限制以后,想要到达右下角,首先肯定要经过第n-K行,所以我们可以将整条路线分成2段。

另外注意不要直接从中间点到达终点,要注意去重。(这里求组合数不能二维数组打表,可用预处理阶乘,

另外,除法模注意用逆元。)

代码实现:

#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define io ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
LL gcd(LL a,LL b)
{
	return b?gcd(b,a%b):a;
}
bool cmp(int x,int y)
{
	return x>y;
}
const int N=2e5+100;
const LL mod=1e9+7;
LL f[N],n,m,A,B;
LL powmod(LL x,LL n)
{
	LL s=1;
	while(n)
	{
		if(n&1)
			s=(s*x)%mod;
		x=(x*x)%mod;
		n>>=1;
	}
	return s;
}
LL C(LL n,LL m)
{
	LL a=f[n];
	LL b=(f[m]*f[n-m])%mod;
	return (a*powmod(b,mod-2))%mod;//逆元
}
int main()
{
	io;
	f[0]=1;
	for(LL i=1; i<N; i++)
		f[i]=(f[i-1]*i)%mod;
	while(cin>>n>>m>>A>>B)
	{
		LL res=0;
		for(LL i=B+1; i<=m; i++)
		{
			LL tmp=(C(i-1+n-A-1,n-A-1)*C(m-i+A-1,m-i))%mod;
			res=(res+tmp)%mod;
		}
		cout<<res<<endl;
	}
	return 0;
}

 

The end;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值