首页 > 其他 > 详细

CF559C

时间:2020-09-05 23:24:10      阅读:50      评论:0      收藏:0      [点我收藏+]

\(x,y\) 的棋盘,从左上角走到右下角,输出方案,\(C_{x+y-2}^{x-1}\)

考虑容斥掉黑色的。把黑色的格子按行、列排序。假设左下角是第\(0\)个黑色格子,右下角是第\(N+1\)个黑格子

\(F[i]\)表示从左上角走到排序后的第\(i\)个黑色格子,不经其他黑色格子的个数

\[F[i]=C_{x_i+y_i-2}^{x_i-1}-\sum_{j=0}^{i-1}F[j]*C_{x_i-x_j+y_i-y_j}^{x_i-x_j}(x_i\ge x_j,y_i\ge y_j) \]

#include<cstdio>
#include<iostream>
#include<algorithm>
#define re register
using namespace std;
#define x first
#define y second
const int N = 2005;
pair<int,int>a[N];
int h,w,n,f[N],mod = 1e9 + 7;
long long jc[200005],inv[200005];
inline int C(int n,int m){return jc[n] * inv[m] % mod * inv[n-m] % mod;}
inline int qpow(long long a,int b){
	long long ans = 1;
	for(;b;b >>= 1){
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	} return ans;
}
int main(){
	scanf("%d%d%d",&h,&w,&n);
	for(re int i = 1;i <= n;++i) scanf("%d%d",&a[i].x,&a[i].y);
	jc[0] = inv[0] = 1;
	for(re int i = 1;i <= 200000;++i){
		jc[i] = jc[i-1] * i % mod;
		inv[i] = qpow(jc[i],mod - 2);
	}
	sort(a + 1,a + n + 1);
	a[n + 1].x = h,a[n + 1].y = w;
	for(re int i = 1;i <= n + 1;++i){
		f[i] = C(a[i].x + a[i].y - 2,a[i].x - 1);
		for(re int j = 1;j < i;++j){
			if(a[j].x > a[i].x || a[j].y > a[i].y) continue;
			f[i] = (f[i] - (long long)f[j] * C(a[i].x+a[i].y-a[j].x-a[j].y,a[i].x-a[j].x)) % mod;
		}
	}
	cout << (f[n + 1] + mod) % mod;
}

CF559C

原文:https://www.cnblogs.com/shikeyu/p/13619384.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!